diff options
author | Roland Dreier <rolandd@cisco.com> | 2006-01-30 17:31:33 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-20 13:08:08 -0500 |
commit | 4885bf64bc2eb242ebebe67077cfe3688283b586 (patch) | |
tree | ed40e3eb7c05e923919f1e8ef2a9186b32c916a4 /drivers/infiniband/hw/mthca/mthca_provider.c | |
parent | 33b9b3ee9709b19c4f02ab91571d53540d05c3d1 (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.c | 127 |
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 | ||
694 | err_free: | 696 | err_free: |
@@ -707,6 +709,121 @@ err_unmap_set: | |||
707 | return ERR_PTR(err); | 709 | return ERR_PTR(err); |
708 | } | 710 | } |
709 | 711 | ||
712 | static 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 | |||
733 | unlock: | ||
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 | |||
757 | static 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 | |||
710 | static int mthca_destroy_cq(struct ib_cq *cq) | 827 | static 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; |