diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_classes.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_main.c | 15 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/hcp_if.c | 27 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/hipz_hw.h | 1 |
5 files changed, 28 insertions, 20 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 87f12d4312a7..74d2b72a11d8 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
| @@ -322,6 +322,7 @@ extern int ehca_static_rate; | |||
| 322 | extern int ehca_port_act_time; | 322 | extern int ehca_port_act_time; |
| 323 | extern int ehca_use_hp_mr; | 323 | extern int ehca_use_hp_mr; |
| 324 | extern int ehca_scaling_code; | 324 | extern int ehca_scaling_code; |
| 325 | extern int ehca_lock_hcalls; | ||
| 325 | 326 | ||
| 326 | struct ipzu_queue_resp { | 327 | struct ipzu_queue_resp { |
| 327 | u32 qe_size; /* queue entry size */ | 328 | u32 qe_size; /* queue entry size */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 90d4334179bf..6a56d86a2951 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
| @@ -43,13 +43,14 @@ | |||
| 43 | #ifdef CONFIG_PPC_64K_PAGES | 43 | #ifdef CONFIG_PPC_64K_PAGES |
| 44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| 45 | #endif | 45 | #endif |
| 46 | |||
| 46 | #include "ehca_classes.h" | 47 | #include "ehca_classes.h" |
| 47 | #include "ehca_iverbs.h" | 48 | #include "ehca_iverbs.h" |
| 48 | #include "ehca_mrmw.h" | 49 | #include "ehca_mrmw.h" |
| 49 | #include "ehca_tools.h" | 50 | #include "ehca_tools.h" |
| 50 | #include "hcp_if.h" | 51 | #include "hcp_if.h" |
| 51 | 52 | ||
| 52 | #define HCAD_VERSION "0024" | 53 | #define HCAD_VERSION "0025" |
| 53 | 54 | ||
| 54 | MODULE_LICENSE("Dual BSD/GPL"); | 55 | MODULE_LICENSE("Dual BSD/GPL"); |
| 55 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 56 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
| @@ -66,6 +67,7 @@ int ehca_poll_all_eqs = 1; | |||
| 66 | int ehca_static_rate = -1; | 67 | int ehca_static_rate = -1; |
| 67 | int ehca_scaling_code = 0; | 68 | int ehca_scaling_code = 0; |
| 68 | int ehca_mr_largepage = 1; | 69 | int ehca_mr_largepage = 1; |
| 70 | int ehca_lock_hcalls = -1; | ||
| 69 | 71 | ||
| 70 | module_param_named(open_aqp1, ehca_open_aqp1, int, S_IRUGO); | 72 | module_param_named(open_aqp1, ehca_open_aqp1, int, S_IRUGO); |
| 71 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); | 73 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); |
| @@ -77,6 +79,7 @@ module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, S_IRUGO); | |||
| 77 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); | 79 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); |
| 78 | module_param_named(scaling_code, ehca_scaling_code, int, S_IRUGO); | 80 | module_param_named(scaling_code, ehca_scaling_code, int, S_IRUGO); |
| 79 | module_param_named(mr_largepage, ehca_mr_largepage, int, S_IRUGO); | 81 | module_param_named(mr_largepage, ehca_mr_largepage, int, S_IRUGO); |
| 82 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); | ||
| 80 | 83 | ||
| 81 | MODULE_PARM_DESC(open_aqp1, | 84 | MODULE_PARM_DESC(open_aqp1, |
| 82 | "AQP1 on startup (0: no (default), 1: yes)"); | 85 | "AQP1 on startup (0: no (default), 1: yes)"); |
| @@ -102,6 +105,9 @@ MODULE_PARM_DESC(scaling_code, | |||
| 102 | MODULE_PARM_DESC(mr_largepage, | 105 | MODULE_PARM_DESC(mr_largepage, |
| 103 | "use large page for MR (0: use PAGE_SIZE (default), " | 106 | "use large page for MR (0: use PAGE_SIZE (default), " |
| 104 | "1: use large page depending on MR size"); | 107 | "1: use large page depending on MR size"); |
| 108 | MODULE_PARM_DESC(lock_hcalls, | ||
| 109 | "serialize all hCalls made by the driver " | ||
| 110 | "(default: autodetect)"); | ||
| 105 | 111 | ||
| 106 | DEFINE_RWLOCK(ehca_qp_idr_lock); | 112 | DEFINE_RWLOCK(ehca_qp_idr_lock); |
| 107 | DEFINE_RWLOCK(ehca_cq_idr_lock); | 113 | DEFINE_RWLOCK(ehca_cq_idr_lock); |
| @@ -258,6 +264,7 @@ static struct cap_descr { | |||
| 258 | { HCA_CAP_UD_LL_QP, "HCA_CAP_UD_LL_QP" }, | 264 | { HCA_CAP_UD_LL_QP, "HCA_CAP_UD_LL_QP" }, |
| 259 | { HCA_CAP_RESIZE_MR, "HCA_CAP_RESIZE_MR" }, | 265 | { HCA_CAP_RESIZE_MR, "HCA_CAP_RESIZE_MR" }, |
| 260 | { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" }, | 266 | { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" }, |
| 267 | { HCA_CAP_H_ALLOC_RES_SYNC, "HCA_CAP_H_ALLOC_RES_SYNC" }, | ||
| 261 | }; | 268 | }; |
| 262 | 269 | ||
| 263 | static int ehca_sense_attributes(struct ehca_shca *shca) | 270 | static int ehca_sense_attributes(struct ehca_shca *shca) |
| @@ -333,6 +340,12 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
| 333 | if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) | 340 | if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) |
| 334 | ehca_gen_dbg(" %s", hca_cap_descr[i].descr); | 341 | ehca_gen_dbg(" %s", hca_cap_descr[i].descr); |
| 335 | 342 | ||
| 343 | /* Autodetect hCall locking -- the "H_ALLOC_RESOURCE synced" flag is | ||
| 344 | * a firmware property, so it's valid across all adapters | ||
| 345 | */ | ||
| 346 | if (ehca_lock_hcalls == -1) | ||
| 347 | ehca_lock_hcalls = !(shca->hca_cap & HCA_CAP_H_ALLOC_RES_SYNC); | ||
| 348 | |||
| 336 | /* translate supported MR page sizes; always support 4K */ | 349 | /* translate supported MR page sizes; always support 4K */ |
| 337 | shca->hca_cap_mr_pgsize = EHCA_PAGESIZE; | 350 | shca->hca_cap_mr_pgsize = EHCA_PAGESIZE; |
| 338 | if (ehca_mr_largepage) { /* support extra sizes only if enabled */ | 351 | if (ehca_mr_largepage) { /* support extra sizes only if enabled */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index dd126681fed0..eff5fb55604b 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
| @@ -838,7 +838,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
| 838 | 838 | ||
| 839 | /* copy back return values */ | 839 | /* copy back return values */ |
| 840 | srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr; | 840 | srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr; |
| 841 | srq_init_attr->attr.max_sge = qp_init_attr.cap.max_recv_sge; | 841 | srq_init_attr->attr.max_sge = 3; |
| 842 | 842 | ||
| 843 | /* drive SRQ into RTR state */ | 843 | /* drive SRQ into RTR state */ |
| 844 | mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); | 844 | mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); |
| @@ -1750,7 +1750,7 @@ int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr) | |||
| 1750 | } | 1750 | } |
| 1751 | 1751 | ||
| 1752 | srq_attr->max_wr = qpcb->max_nr_outst_recv_wr - 1; | 1752 | srq_attr->max_wr = qpcb->max_nr_outst_recv_wr - 1; |
| 1753 | srq_attr->max_sge = qpcb->actual_nr_sges_in_rq_wqe; | 1753 | srq_attr->max_sge = 3; |
| 1754 | srq_attr->srq_limit = EHCA_BMASK_GET( | 1754 | srq_attr->srq_limit = EHCA_BMASK_GET( |
| 1755 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); | 1755 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); |
| 1756 | 1756 | ||
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index c16a21374bb5..7029aa653751 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c | |||
| @@ -120,26 +120,21 @@ static long ehca_plpar_hcall_norets(unsigned long opcode, | |||
| 120 | unsigned long arg7) | 120 | unsigned long arg7) |
| 121 | { | 121 | { |
| 122 | long ret; | 122 | long ret; |
| 123 | int i, sleep_msecs, do_lock; | 123 | int i, sleep_msecs; |
| 124 | unsigned long flags; | 124 | unsigned long flags = 0; |
| 125 | 125 | ||
| 126 | ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT, | 126 | ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT, |
| 127 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); | 127 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
| 128 | 128 | ||
| 129 | /* lock H_FREE_RESOURCE(MR) against itself and H_ALLOC_RESOURCE(MR) */ | ||
| 130 | if ((opcode == H_FREE_RESOURCE) && (arg7 == 5)) { | ||
| 131 | arg7 = 0; /* better not upset firmware */ | ||
| 132 | do_lock = 1; | ||
| 133 | } | ||
| 134 | |||
| 135 | for (i = 0; i < 5; i++) { | 129 | for (i = 0; i < 5; i++) { |
| 136 | if (do_lock) | 130 | /* serialize hCalls to work around firmware issue */ |
| 131 | if (ehca_lock_hcalls) | ||
| 137 | spin_lock_irqsave(&hcall_lock, flags); | 132 | spin_lock_irqsave(&hcall_lock, flags); |
| 138 | 133 | ||
| 139 | ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, | 134 | ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, |
| 140 | arg5, arg6, arg7); | 135 | arg5, arg6, arg7); |
| 141 | 136 | ||
| 142 | if (do_lock) | 137 | if (ehca_lock_hcalls) |
| 143 | spin_unlock_irqrestore(&hcall_lock, flags); | 138 | spin_unlock_irqrestore(&hcall_lock, flags); |
| 144 | 139 | ||
| 145 | if (H_IS_LONG_BUSY(ret)) { | 140 | if (H_IS_LONG_BUSY(ret)) { |
| @@ -174,24 +169,22 @@ static long ehca_plpar_hcall9(unsigned long opcode, | |||
| 174 | unsigned long arg9) | 169 | unsigned long arg9) |
| 175 | { | 170 | { |
| 176 | long ret; | 171 | long ret; |
| 177 | int i, sleep_msecs, do_lock; | 172 | int i, sleep_msecs; |
| 178 | unsigned long flags = 0; | 173 | unsigned long flags = 0; |
| 179 | 174 | ||
| 180 | ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, | 175 | ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, |
| 181 | arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); | 176 | arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); |
| 182 | 177 | ||
| 183 | /* lock H_ALLOC_RESOURCE(MR) against itself and H_FREE_RESOURCE(MR) */ | ||
| 184 | do_lock = ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)); | ||
| 185 | |||
| 186 | for (i = 0; i < 5; i++) { | 178 | for (i = 0; i < 5; i++) { |
| 187 | if (do_lock) | 179 | /* serialize hCalls to work around firmware issue */ |
| 180 | if (ehca_lock_hcalls) | ||
| 188 | spin_lock_irqsave(&hcall_lock, flags); | 181 | spin_lock_irqsave(&hcall_lock, flags); |
| 189 | 182 | ||
| 190 | ret = plpar_hcall9(opcode, outs, | 183 | ret = plpar_hcall9(opcode, outs, |
| 191 | arg1, arg2, arg3, arg4, arg5, | 184 | arg1, arg2, arg3, arg4, arg5, |
| 192 | arg6, arg7, arg8, arg9); | 185 | arg6, arg7, arg8, arg9); |
| 193 | 186 | ||
| 194 | if (do_lock) | 187 | if (ehca_lock_hcalls) |
| 195 | spin_unlock_irqrestore(&hcall_lock, flags); | 188 | spin_unlock_irqrestore(&hcall_lock, flags); |
| 196 | 189 | ||
| 197 | if (H_IS_LONG_BUSY(ret)) { | 190 | if (H_IS_LONG_BUSY(ret)) { |
| @@ -821,7 +814,7 @@ u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle, | |||
| 821 | return ehca_plpar_hcall_norets(H_FREE_RESOURCE, | 814 | return ehca_plpar_hcall_norets(H_FREE_RESOURCE, |
| 822 | adapter_handle.handle, /* r4 */ | 815 | adapter_handle.handle, /* r4 */ |
| 823 | mr->ipz_mr_handle.handle, /* r5 */ | 816 | mr->ipz_mr_handle.handle, /* r5 */ |
| 824 | 0, 0, 0, 0, 5); | 817 | 0, 0, 0, 0, 0); |
| 825 | } | 818 | } |
| 826 | 819 | ||
| 827 | u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle, | 820 | u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle, |
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h index 485b8400359e..bf996c7acc42 100644 --- a/drivers/infiniband/hw/ehca/hipz_hw.h +++ b/drivers/infiniband/hw/ehca/hipz_hw.h | |||
| @@ -378,6 +378,7 @@ struct hipz_query_hca { | |||
| 378 | #define HCA_CAP_UD_LL_QP EHCA_BMASK_IBM(16, 16) | 378 | #define HCA_CAP_UD_LL_QP EHCA_BMASK_IBM(16, 16) |
| 379 | #define HCA_CAP_RESIZE_MR EHCA_BMASK_IBM(17, 17) | 379 | #define HCA_CAP_RESIZE_MR EHCA_BMASK_IBM(17, 17) |
| 380 | #define HCA_CAP_MINI_QP EHCA_BMASK_IBM(18, 18) | 380 | #define HCA_CAP_MINI_QP EHCA_BMASK_IBM(18, 18) |
| 381 | #define HCA_CAP_H_ALLOC_RES_SYNC EHCA_BMASK_IBM(19, 19) | ||
| 381 | 382 | ||
| 382 | /* query port response block */ | 383 | /* query port response block */ |
| 383 | struct hipz_query_port { | 384 | struct hipz_query_port { |
