0001
0002
0003
0004
0005
0006
0007 #include <linux/vmalloc.h>
0008 #include "rxe.h"
0009 #include "rxe_queue.h"
0010
0011 int rxe_srq_chk_init(struct rxe_dev *rxe, struct ib_srq_init_attr *init)
0012 {
0013 struct ib_srq_attr *attr = &init->attr;
0014
0015 if (attr->max_wr > rxe->attr.max_srq_wr) {
0016 pr_warn("max_wr(%d) > max_srq_wr(%d)\n",
0017 attr->max_wr, rxe->attr.max_srq_wr);
0018 goto err1;
0019 }
0020
0021 if (attr->max_wr <= 0) {
0022 pr_warn("max_wr(%d) <= 0\n", attr->max_wr);
0023 goto err1;
0024 }
0025
0026 if (attr->max_wr < RXE_MIN_SRQ_WR)
0027 attr->max_wr = RXE_MIN_SRQ_WR;
0028
0029 if (attr->max_sge > rxe->attr.max_srq_sge) {
0030 pr_warn("max_sge(%d) > max_srq_sge(%d)\n",
0031 attr->max_sge, rxe->attr.max_srq_sge);
0032 goto err1;
0033 }
0034
0035 if (attr->max_sge < RXE_MIN_SRQ_SGE)
0036 attr->max_sge = RXE_MIN_SRQ_SGE;
0037
0038 return 0;
0039
0040 err1:
0041 return -EINVAL;
0042 }
0043
0044 int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,
0045 struct ib_srq_init_attr *init, struct ib_udata *udata,
0046 struct rxe_create_srq_resp __user *uresp)
0047 {
0048 int err;
0049 int srq_wqe_size;
0050 struct rxe_queue *q;
0051 enum queue_type type;
0052
0053 srq->ibsrq.event_handler = init->event_handler;
0054 srq->ibsrq.srq_context = init->srq_context;
0055 srq->limit = init->attr.srq_limit;
0056 srq->srq_num = srq->elem.index;
0057 srq->rq.max_wr = init->attr.max_wr;
0058 srq->rq.max_sge = init->attr.max_sge;
0059
0060 srq_wqe_size = rcv_wqe_size(srq->rq.max_sge);
0061
0062 spin_lock_init(&srq->rq.producer_lock);
0063 spin_lock_init(&srq->rq.consumer_lock);
0064
0065 type = QUEUE_TYPE_FROM_CLIENT;
0066 q = rxe_queue_init(rxe, &srq->rq.max_wr, srq_wqe_size, type);
0067 if (!q) {
0068 pr_warn("unable to allocate queue for srq\n");
0069 return -ENOMEM;
0070 }
0071
0072 srq->rq.queue = q;
0073
0074 err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata, q->buf,
0075 q->buf_size, &q->ip);
0076 if (err) {
0077 vfree(q->buf);
0078 kfree(q);
0079 return err;
0080 }
0081
0082 if (uresp) {
0083 if (copy_to_user(&uresp->srq_num, &srq->srq_num,
0084 sizeof(uresp->srq_num))) {
0085 rxe_queue_cleanup(q);
0086 return -EFAULT;
0087 }
0088 }
0089
0090 return 0;
0091 }
0092
0093 int rxe_srq_chk_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
0094 struct ib_srq_attr *attr, enum ib_srq_attr_mask mask)
0095 {
0096 if (srq->error) {
0097 pr_warn("srq in error state\n");
0098 goto err1;
0099 }
0100
0101 if (mask & IB_SRQ_MAX_WR) {
0102 if (attr->max_wr > rxe->attr.max_srq_wr) {
0103 pr_warn("max_wr(%d) > max_srq_wr(%d)\n",
0104 attr->max_wr, rxe->attr.max_srq_wr);
0105 goto err1;
0106 }
0107
0108 if (attr->max_wr <= 0) {
0109 pr_warn("max_wr(%d) <= 0\n", attr->max_wr);
0110 goto err1;
0111 }
0112
0113 if (srq->limit && (attr->max_wr < srq->limit)) {
0114 pr_warn("max_wr (%d) < srq->limit (%d)\n",
0115 attr->max_wr, srq->limit);
0116 goto err1;
0117 }
0118
0119 if (attr->max_wr < RXE_MIN_SRQ_WR)
0120 attr->max_wr = RXE_MIN_SRQ_WR;
0121 }
0122
0123 if (mask & IB_SRQ_LIMIT) {
0124 if (attr->srq_limit > rxe->attr.max_srq_wr) {
0125 pr_warn("srq_limit(%d) > max_srq_wr(%d)\n",
0126 attr->srq_limit, rxe->attr.max_srq_wr);
0127 goto err1;
0128 }
0129
0130 if (attr->srq_limit > srq->rq.queue->buf->index_mask) {
0131 pr_warn("srq_limit (%d) > cur limit(%d)\n",
0132 attr->srq_limit,
0133 srq->rq.queue->buf->index_mask);
0134 goto err1;
0135 }
0136 }
0137
0138 return 0;
0139
0140 err1:
0141 return -EINVAL;
0142 }
0143
0144 int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
0145 struct ib_srq_attr *attr, enum ib_srq_attr_mask mask,
0146 struct rxe_modify_srq_cmd *ucmd, struct ib_udata *udata)
0147 {
0148 int err;
0149 struct rxe_queue *q = srq->rq.queue;
0150 struct mminfo __user *mi = NULL;
0151
0152 if (mask & IB_SRQ_MAX_WR) {
0153
0154
0155
0156
0157 mi = u64_to_user_ptr(ucmd->mmap_info_addr);
0158
0159 err = rxe_queue_resize(q, &attr->max_wr,
0160 rcv_wqe_size(srq->rq.max_sge), udata, mi,
0161 &srq->rq.producer_lock,
0162 &srq->rq.consumer_lock);
0163 if (err)
0164 goto err2;
0165 }
0166
0167 if (mask & IB_SRQ_LIMIT)
0168 srq->limit = attr->srq_limit;
0169
0170 return 0;
0171
0172 err2:
0173 rxe_queue_cleanup(q);
0174 srq->rq.queue = NULL;
0175 return err;
0176 }
0177
0178 void rxe_srq_cleanup(struct rxe_pool_elem *elem)
0179 {
0180 struct rxe_srq *srq = container_of(elem, typeof(*srq), elem);
0181
0182 if (srq->pd)
0183 rxe_put(srq->pd);
0184
0185 if (srq->rq.queue)
0186 rxe_queue_cleanup(srq->rq.queue);
0187 }