aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca/mthca_provider.c
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2006-01-30 17:31:33 -0500
committerRoland Dreier <rolandd@cisco.com>2006-03-20 13:08:08 -0500
commit4885bf64bc2eb242ebebe67077cfe3688283b586 (patch)
treeed40e3eb7c05e923919f1e8ef2a9186b32c916a4 /drivers/infiniband/hw/mthca/mthca_provider.c
parent33b9b3ee9709b19c4f02ab91571d53540d05c3d1 (diff)
IB/mthca: Add device-specific support for resizing CQs
Add low-level driver support for resizing CQs (both kernel and userspace) to mthca. Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_provider.c')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c127
1 files changed, 123 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index e88e39aef85a..cd2038bdd1ac 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved. 6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
7 * 7 *
@@ -669,9 +669,9 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
669 } 669 }
670 670
671 if (context) { 671 if (context) {
672 cq->mr.ibmr.lkey = ucmd.lkey; 672 cq->buf.mr.ibmr.lkey = ucmd.lkey;
673 cq->set_ci_db_index = ucmd.set_db_index; 673 cq->set_ci_db_index = ucmd.set_db_index;
674 cq->arm_db_index = ucmd.arm_db_index; 674 cq->arm_db_index = ucmd.arm_db_index;
675 } 675 }
676 676
677 for (nent = 1; nent <= entries; nent <<= 1) 677 for (nent = 1; nent <= entries; nent <<= 1)
@@ -689,6 +689,8 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
689 goto err_free; 689 goto err_free;
690 } 690 }
691 691
692 cq->resize_buf = NULL;
693
692 return &cq->ibcq; 694 return &cq->ibcq;
693 695
694err_free: 696err_free:
@@ -707,6 +709,121 @@ err_unmap_set:
707 return ERR_PTR(err); 709 return ERR_PTR(err);
708} 710}
709 711
712static int mthca_alloc_resize_buf(struct mthca_dev *dev, struct mthca_cq *cq,
713 int entries)
714{
715 int ret;
716
717 spin_lock_irq(&cq->lock);
718 if (cq->resize_buf) {
719 ret = -EBUSY;
720 goto unlock;
721 }
722
723 cq->resize_buf = kmalloc(sizeof *cq->resize_buf, GFP_ATOMIC);
724 if (!cq->resize_buf) {
725 ret = -ENOMEM;
726 goto unlock;
727 }
728
729 cq->resize_buf->state = CQ_RESIZE_ALLOC;
730
731 ret = 0;
732
733unlock:
734 spin_unlock_irq(&cq->lock);
735
736 if (ret)
737 return ret;
738
739 ret = mthca_alloc_cq_buf(dev, &cq->resize_buf->buf, entries);
740 if (ret) {
741 spin_lock_irq(&cq->lock);
742 kfree(cq->resize_buf);
743 cq->resize_buf = NULL;
744 spin_unlock_irq(&cq->lock);
745 return ret;
746 }
747
748 cq->resize_buf->cqe = entries - 1;
749
750 spin_lock_irq(&cq->lock);
751 cq->resize_buf->state = CQ_RESIZE_READY;
752 spin_unlock_irq(&cq->lock);
753
754 return 0;
755}
756
757static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
758{
759 struct mthca_dev *dev = to_mdev(ibcq->device);
760 struct mthca_cq *cq = to_mcq(ibcq);
761 struct mthca_resize_cq ucmd;
762 u32 lkey;
763 u8 status;
764 int ret;
765
766 if (entries < 1 || entries > dev->limits.max_cqes)
767 return -EINVAL;
768
769 entries = roundup_pow_of_two(entries + 1);
770 if (entries == ibcq->cqe + 1)
771 return 0;
772
773 if (cq->is_kernel) {
774 ret = mthca_alloc_resize_buf(dev, cq, entries);
775 if (ret)
776 return ret;
777 lkey = cq->resize_buf->buf.mr.ibmr.lkey;
778 } else {
779 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
780 return -EFAULT;
781 lkey = ucmd.lkey;
782 }
783
784 ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, long_log2(entries), &status);
785 if (status)
786 ret = -EINVAL;
787
788 if (ret) {
789 if (cq->resize_buf) {
790 mthca_free_cq_buf(dev, &cq->resize_buf->buf,
791 cq->resize_buf->cqe);
792 kfree(cq->resize_buf);
793 spin_lock_irq(&cq->lock);
794 cq->resize_buf = NULL;
795 spin_unlock_irq(&cq->lock);
796 }
797 return ret;
798 }
799
800 if (cq->is_kernel) {
801 struct mthca_cq_buf tbuf;
802 int tcqe;
803
804 spin_lock_irq(&cq->lock);
805 if (cq->resize_buf->state == CQ_RESIZE_READY) {
806 mthca_cq_resize_copy_cqes(cq);
807 tbuf = cq->buf;
808 tcqe = cq->ibcq.cqe;
809 cq->buf = cq->resize_buf->buf;
810 cq->ibcq.cqe = cq->resize_buf->cqe;
811 } else {
812 tbuf = cq->resize_buf->buf;
813 tcqe = cq->resize_buf->cqe;
814 }
815
816 kfree(cq->resize_buf);
817 cq->resize_buf = NULL;
818 spin_unlock_irq(&cq->lock);
819
820 mthca_free_cq_buf(dev, &tbuf, tcqe);
821 } else
822 ibcq->cqe = entries - 1;
823
824 return 0;
825}
826
710static int mthca_destroy_cq(struct ib_cq *cq) 827static int mthca_destroy_cq(struct ib_cq *cq)
711{ 828{
712 if (cq->uobject) { 829 if (cq->uobject) {
@@ -1113,6 +1230,7 @@ int mthca_register_device(struct mthca_dev *dev)
1113 (1ull << IB_USER_VERBS_CMD_DEREG_MR) | 1230 (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
1114 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | 1231 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
1115 (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | 1232 (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
1233 (1ull << IB_USER_VERBS_CMD_RESIZE_CQ) |
1116 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) | 1234 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
1117 (1ull << IB_USER_VERBS_CMD_CREATE_QP) | 1235 (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
1118 (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | 1236 (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
@@ -1154,6 +1272,7 @@ int mthca_register_device(struct mthca_dev *dev)
1154 dev->ib_dev.modify_qp = mthca_modify_qp; 1272 dev->ib_dev.modify_qp = mthca_modify_qp;
1155 dev->ib_dev.destroy_qp = mthca_destroy_qp; 1273 dev->ib_dev.destroy_qp = mthca_destroy_qp;
1156 dev->ib_dev.create_cq = mthca_create_cq; 1274 dev->ib_dev.create_cq = mthca_create_cq;
1275 dev->ib_dev.resize_cq = mthca_resize_cq;
1157 dev->ib_dev.destroy_cq = mthca_destroy_cq; 1276 dev->ib_dev.destroy_cq = mthca_destroy_cq;
1158 dev->ib_dev.poll_cq = mthca_poll_cq; 1277 dev->ib_dev.poll_cq = mthca_poll_cq;
1159 dev->ib_dev.get_dma_mr = mthca_get_dma_mr; 1278 dev->ib_dev.get_dma_mr = mthca_get_dma_mr;