diff options
author | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 10:57:55 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 10:57:55 -0400 |
commit | 7022b15e2a9f878fd5184586064c63352c3dd225 (patch) | |
tree | 5365c2f5bc82ae1946636ee8d5cd5d3b7e804f1b /drivers/infiniband/hw/ehca/ehca_qp.c | |
parent | aaad2b0c757f3e6e02552cb0bdcd91a5ec0d6305 (diff) | |
parent | a15306365a16380f3bafee9e181ba01231d4acd7 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_qp.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 3eb14a52cbf2..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 | ||
@@ -550,6 +570,7 @@ static struct ehca_qp *internal_create_qp( | |||
550 | spin_lock_init(&my_qp->spinlock_r); | 570 | spin_lock_init(&my_qp->spinlock_r); |
551 | my_qp->qp_type = qp_type; | 571 | my_qp->qp_type = qp_type; |
552 | my_qp->ext_type = parms.ext_type; | 572 | my_qp->ext_type = parms.ext_type; |
573 | my_qp->state = IB_QPS_RESET; | ||
553 | 574 | ||
554 | if (init_attr->recv_cq) | 575 | if (init_attr->recv_cq) |
555 | my_qp->recv_cq = | 576 | my_qp->recv_cq = |
@@ -822,6 +843,7 @@ create_qp_exit1: | |||
822 | 843 | ||
823 | create_qp_exit0: | 844 | create_qp_exit0: |
824 | kmem_cache_free(qp_cache, my_qp); | 845 | kmem_cache_free(qp_cache, my_qp); |
846 | atomic_dec(&shca->num_qps); | ||
825 | return ERR_PTR(ret); | 847 | return ERR_PTR(ret); |
826 | } | 848 | } |
827 | 849 | ||
@@ -965,7 +987,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, | |||
965 | qp_num, bad_send_wqe_p); | 987 | qp_num, bad_send_wqe_p); |
966 | /* convert wqe pointer to vadr */ | 988 | /* convert wqe pointer to vadr */ |
967 | bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p); | 989 | bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p); |
968 | if (ehca_debug_level) | 990 | if (ehca_debug_level >= 2) |
969 | ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); | 991 | ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); |
970 | squeue = &my_qp->ipz_squeue; | 992 | squeue = &my_qp->ipz_squeue; |
971 | if (ipz_queue_abs_to_offset(squeue, (u64)bad_send_wqe_p, &q_ofs)) { | 993 | if (ipz_queue_abs_to_offset(squeue, (u64)bad_send_wqe_p, &q_ofs)) { |
@@ -978,7 +1000,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, | |||
978 | wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs); | 1000 | wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs); |
979 | *bad_wqe_cnt = 0; | 1001 | *bad_wqe_cnt = 0; |
980 | while (wqe->optype != 0xff && wqe->wqef != 0xff) { | 1002 | while (wqe->optype != 0xff && wqe->wqef != 0xff) { |
981 | if (ehca_debug_level) | 1003 | if (ehca_debug_level >= 2) |
982 | ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num); | 1004 | ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num); |
983 | wqe->nr_of_data_seg = 0; /* suppress data access */ | 1005 | wqe->nr_of_data_seg = 0; /* suppress data access */ |
984 | wqe->wqef = WQEF_PURGE; /* WQE to be purged */ | 1006 | wqe->wqef = WQEF_PURGE; /* WQE to be purged */ |
@@ -1450,7 +1472,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1450 | /* no support for max_send/recv_sge yet */ | 1472 | /* no support for max_send/recv_sge yet */ |
1451 | } | 1473 | } |
1452 | 1474 | ||
1453 | if (ehca_debug_level) | 1475 | if (ehca_debug_level >= 2) |
1454 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", ibqp->qp_num); | 1476 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", ibqp->qp_num); |
1455 | 1477 | ||
1456 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, | 1478 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, |
@@ -1508,6 +1530,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1508 | if (attr_mask & IB_QP_QKEY) | 1530 | if (attr_mask & IB_QP_QKEY) |
1509 | my_qp->qkey = attr->qkey; | 1531 | my_qp->qkey = attr->qkey; |
1510 | 1532 | ||
1533 | my_qp->state = qp_new_state; | ||
1534 | |||
1511 | modify_qp_exit2: | 1535 | modify_qp_exit2: |
1512 | if (squeue_locked) { /* this means: sqe -> rts */ | 1536 | if (squeue_locked) { /* this means: sqe -> rts */ |
1513 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); | 1537 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); |
@@ -1763,7 +1787,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1763 | if (qp_init_attr) | 1787 | if (qp_init_attr) |
1764 | *qp_init_attr = my_qp->init_attr; | 1788 | *qp_init_attr = my_qp->init_attr; |
1765 | 1789 | ||
1766 | if (ehca_debug_level) | 1790 | if (ehca_debug_level >= 2) |
1767 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); | 1791 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); |
1768 | 1792 | ||
1769 | query_qp_exit1: | 1793 | query_qp_exit1: |
@@ -1811,7 +1835,7 @@ int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | |||
1811 | goto modify_srq_exit0; | 1835 | goto modify_srq_exit0; |
1812 | } | 1836 | } |
1813 | 1837 | ||
1814 | if (ehca_debug_level) | 1838 | if (ehca_debug_level >= 2) |
1815 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); | 1839 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); |
1816 | 1840 | ||
1817 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle, | 1841 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle, |
@@ -1864,7 +1888,7 @@ int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr) | |||
1864 | srq_attr->srq_limit = EHCA_BMASK_GET( | 1888 | srq_attr->srq_limit = EHCA_BMASK_GET( |
1865 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); | 1889 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); |
1866 | 1890 | ||
1867 | if (ehca_debug_level) | 1891 | if (ehca_debug_level >= 2) |
1868 | ehca_dmp(qpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); | 1892 | ehca_dmp(qpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); |
1869 | 1893 | ||
1870 | query_srq_exit1: | 1894 | query_srq_exit1: |
@@ -1945,6 +1969,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
1945 | if (HAS_SQ(my_qp)) | 1969 | if (HAS_SQ(my_qp)) |
1946 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); | 1970 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); |
1947 | kmem_cache_free(qp_cache, my_qp); | 1971 | kmem_cache_free(qp_cache, my_qp); |
1972 | atomic_dec(&shca->num_qps); | ||
1948 | return 0; | 1973 | return 0; |
1949 | } | 1974 | } |
1950 | 1975 | ||