diff options
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_classes.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_cq.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_main.c | 83 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 10 |
5 files changed, 81 insertions, 19 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index c325c44807e8..44e936e48a31 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -1942,6 +1942,7 @@ fail4: | |||
1942 | fail3: | 1942 | fail3: |
1943 | cxgb3_free_atid(ep->com.tdev, ep->atid); | 1943 | cxgb3_free_atid(ep->com.tdev, ep->atid); |
1944 | fail2: | 1944 | fail2: |
1945 | cm_id->rem_ref(cm_id); | ||
1945 | put_ep(&ep->com); | 1946 | put_ep(&ep->com); |
1946 | out: | 1947 | out: |
1947 | return err; | 1948 | return err; |
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..bb02a86aa526 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #include <linux/notifier.h> | ||
48 | #include <linux/memory.h> | ||
47 | #include "ehca_classes.h" | 49 | #include "ehca_classes.h" |
48 | #include "ehca_iverbs.h" | 50 | #include "ehca_iverbs.h" |
49 | #include "ehca_mrmw.h" | 51 | #include "ehca_mrmw.h" |
@@ -366,22 +368,23 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
366 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; | 368 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; |
367 | 369 | ||
368 | /* Set maximum number of CQs and QPs to calculate EQ size */ | 370 | /* Set maximum number of CQs and QPs to calculate EQ size */ |
369 | if (ehca_max_qp == -1) | 371 | if (shca->max_num_qps == -1) |
370 | ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES); | 372 | shca->max_num_qps = min_t(int, rblock->max_qp, |
371 | else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) { | 373 | EHCA_MAX_NUM_QUEUES); |
372 | ehca_gen_err("Requested number of QPs is out of range (1 - %i) " | 374 | else if (shca->max_num_qps < 1 || shca->max_num_qps > rblock->max_qp) { |
373 | "specified by HW", rblock->max_qp); | 375 | ehca_gen_warn("The requested number of QPs is out of range " |
374 | ret = -EINVAL; | 376 | "(1 - %i) specified by HW. Value is set to %i", |
375 | goto sense_attributes1; | 377 | rblock->max_qp, rblock->max_qp); |
378 | shca->max_num_qps = rblock->max_qp; | ||
376 | } | 379 | } |
377 | 380 | ||
378 | if (ehca_max_cq == -1) | 381 | if (shca->max_num_cqs == -1) |
379 | ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES); | 382 | shca->max_num_cqs = min_t(int, rblock->max_cq, |
380 | else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) { | 383 | EHCA_MAX_NUM_QUEUES); |
381 | ehca_gen_err("Requested number of CQs is out of range (1 - %i) " | 384 | else if (shca->max_num_cqs < 1 || shca->max_num_cqs > rblock->max_cq) { |
382 | "specified by HW", rblock->max_cq); | 385 | ehca_gen_warn("The requested number of CQs is out of range " |
383 | ret = -EINVAL; | 386 | "(1 - %i) specified by HW. Value is set to %i", |
384 | goto sense_attributes1; | 387 | rblock->max_cq, rblock->max_cq); |
385 | } | 388 | } |
386 | 389 | ||
387 | /* query max MTU from first port -- it's the same for all ports */ | 390 | /* query max MTU from first port -- it's the same for all ports */ |
@@ -733,9 +736,13 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
733 | ehca_gen_err("Cannot allocate shca memory."); | 736 | ehca_gen_err("Cannot allocate shca memory."); |
734 | return -ENOMEM; | 737 | return -ENOMEM; |
735 | } | 738 | } |
739 | |||
736 | mutex_init(&shca->modify_mutex); | 740 | mutex_init(&shca->modify_mutex); |
737 | atomic_set(&shca->num_cqs, 0); | 741 | atomic_set(&shca->num_cqs, 0); |
738 | atomic_set(&shca->num_qps, 0); | 742 | atomic_set(&shca->num_qps, 0); |
743 | shca->max_num_qps = ehca_max_qp; | ||
744 | shca->max_num_cqs = ehca_max_cq; | ||
745 | |||
739 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) | 746 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) |
740 | spin_lock_init(&shca->sport[i].mod_sqp_lock); | 747 | spin_lock_init(&shca->sport[i].mod_sqp_lock); |
741 | 748 | ||
@@ -755,7 +762,7 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
755 | goto probe1; | 762 | goto probe1; |
756 | } | 763 | } |
757 | 764 | ||
758 | eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp; | 765 | eq_size = 2 * shca->max_num_cqs + 4 * shca->max_num_qps; |
759 | /* create event queues */ | 766 | /* create event queues */ |
760 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); | 767 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); |
761 | if (ret) { | 768 | if (ret) { |
@@ -964,6 +971,41 @@ void ehca_poll_eqs(unsigned long data) | |||
964 | spin_unlock(&shca_list_lock); | 971 | spin_unlock(&shca_list_lock); |
965 | } | 972 | } |
966 | 973 | ||
974 | static int ehca_mem_notifier(struct notifier_block *nb, | ||
975 | unsigned long action, void *data) | ||
976 | { | ||
977 | static unsigned long ehca_dmem_warn_time; | ||
978 | |||
979 | switch (action) { | ||
980 | case MEM_CANCEL_OFFLINE: | ||
981 | case MEM_CANCEL_ONLINE: | ||
982 | case MEM_ONLINE: | ||
983 | case MEM_OFFLINE: | ||
984 | return NOTIFY_OK; | ||
985 | case MEM_GOING_ONLINE: | ||
986 | case MEM_GOING_OFFLINE: | ||
987 | /* only ok if no hca is attached to the lpar */ | ||
988 | spin_lock(&shca_list_lock); | ||
989 | if (list_empty(&shca_list)) { | ||
990 | spin_unlock(&shca_list_lock); | ||
991 | return NOTIFY_OK; | ||
992 | } else { | ||
993 | spin_unlock(&shca_list_lock); | ||
994 | if (printk_timed_ratelimit(&ehca_dmem_warn_time, | ||
995 | 30 * 1000)) | ||
996 | ehca_gen_err("DMEM operations are not allowed" | ||
997 | "as long as an ehca adapter is" | ||
998 | "attached to the LPAR"); | ||
999 | return NOTIFY_BAD; | ||
1000 | } | ||
1001 | } | ||
1002 | return NOTIFY_OK; | ||
1003 | } | ||
1004 | |||
1005 | static struct notifier_block ehca_mem_nb = { | ||
1006 | .notifier_call = ehca_mem_notifier, | ||
1007 | }; | ||
1008 | |||
967 | static int __init ehca_module_init(void) | 1009 | static int __init ehca_module_init(void) |
968 | { | 1010 | { |
969 | int ret; | 1011 | int ret; |
@@ -991,6 +1033,12 @@ static int __init ehca_module_init(void) | |||
991 | goto module_init2; | 1033 | goto module_init2; |
992 | } | 1034 | } |
993 | 1035 | ||
1036 | ret = register_memory_notifier(&ehca_mem_nb); | ||
1037 | if (ret) { | ||
1038 | ehca_gen_err("Failed registering memory add/remove notifier"); | ||
1039 | goto module_init3; | ||
1040 | } | ||
1041 | |||
994 | if (ehca_poll_all_eqs != 1) { | 1042 | if (ehca_poll_all_eqs != 1) { |
995 | ehca_gen_err("WARNING!!!"); | 1043 | ehca_gen_err("WARNING!!!"); |
996 | ehca_gen_err("It is possible to lose interrupts."); | 1044 | ehca_gen_err("It is possible to lose interrupts."); |
@@ -1003,6 +1051,9 @@ static int __init ehca_module_init(void) | |||
1003 | 1051 | ||
1004 | return 0; | 1052 | return 0; |
1005 | 1053 | ||
1054 | module_init3: | ||
1055 | ibmebus_unregister_driver(&ehca_driver); | ||
1056 | |||
1006 | module_init2: | 1057 | module_init2: |
1007 | ehca_destroy_slab_caches(); | 1058 | ehca_destroy_slab_caches(); |
1008 | 1059 | ||
@@ -1018,6 +1069,8 @@ static void __exit ehca_module_exit(void) | |||
1018 | 1069 | ||
1019 | ibmebus_unregister_driver(&ehca_driver); | 1070 | ibmebus_unregister_driver(&ehca_driver); |
1020 | 1071 | ||
1072 | unregister_memory_notifier(&ehca_mem_nb); | ||
1073 | |||
1021 | ehca_destroy_slab_caches(); | 1074 | ehca_destroy_slab_caches(); |
1022 | 1075 | ||
1023 | ehca_destroy_comp_pool(); | 1076 | ehca_destroy_comp_pool(); |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4dbe2870e014..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); |
@@ -502,6 +502,12 @@ static struct ehca_qp *internal_create_qp( | |||
502 | if (init_attr->srq) { | 502 | if (init_attr->srq) { |
503 | my_srq = container_of(init_attr->srq, struct ehca_qp, ib_srq); | 503 | my_srq = container_of(init_attr->srq, struct ehca_qp, ib_srq); |
504 | 504 | ||
505 | if (qp_type == IB_QPT_UC) { | ||
506 | ehca_err(pd->device, "UC with SRQ not supported"); | ||
507 | atomic_dec(&shca->num_qps); | ||
508 | return ERR_PTR(-EINVAL); | ||
509 | } | ||
510 | |||
505 | has_srq = 1; | 511 | has_srq = 1; |
506 | parms.ext_type = EQPT_SRQBASE; | 512 | parms.ext_type = EQPT_SRQBASE; |
507 | parms.srq_qpn = my_srq->real_qp_num; | 513 | parms.srq_qpn = my_srq->real_qp_num; |