brintos

brintos / linux-shallow public Read only

0
0
Text · 4.4 KiB · 3661cb6 Raw
200 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB2/*3 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.4 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.5 */6 7#include <linux/vmalloc.h>8#include "rxe.h"9#include "rxe_queue.h"10 11int rxe_srq_chk_init(struct rxe_dev *rxe, struct ib_srq_init_attr *init)12{13	struct ib_srq_attr *attr = &init->attr;14 15	if (attr->max_wr > rxe->attr.max_srq_wr) {16		rxe_dbg_dev(rxe, "max_wr(%d) > max_srq_wr(%d)\n",17			attr->max_wr, rxe->attr.max_srq_wr);18		goto err1;19	}20 21	if (attr->max_wr <= 0) {22		rxe_dbg_dev(rxe, "max_wr(%d) <= 0\n", attr->max_wr);23		goto err1;24	}25 26	if (attr->max_wr < RXE_MIN_SRQ_WR)27		attr->max_wr = RXE_MIN_SRQ_WR;28 29	if (attr->max_sge > rxe->attr.max_srq_sge) {30		rxe_dbg_dev(rxe, "max_sge(%d) > max_srq_sge(%d)\n",31			attr->max_sge, rxe->attr.max_srq_sge);32		goto err1;33	}34 35	if (attr->max_sge < RXE_MIN_SRQ_SGE)36		attr->max_sge = RXE_MIN_SRQ_SGE;37 38	return 0;39 40err1:41	return -EINVAL;42}43 44int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,45		      struct ib_srq_init_attr *init, struct ib_udata *udata,46		      struct rxe_create_srq_resp __user *uresp)47{48	struct rxe_queue *q;49	int wqe_size;50	int err;51 52	srq->ibsrq.event_handler = init->event_handler;53	srq->ibsrq.srq_context = init->srq_context;54	srq->limit = init->attr.srq_limit;55	srq->srq_num = srq->elem.index;56	srq->rq.max_wr = init->attr.max_wr;57	srq->rq.max_sge = init->attr.max_sge;58 59	wqe_size = sizeof(struct rxe_recv_wqe) +60			srq->rq.max_sge*sizeof(struct ib_sge);61 62	spin_lock_init(&srq->rq.producer_lock);63	spin_lock_init(&srq->rq.consumer_lock);64 65	q = rxe_queue_init(rxe, &srq->rq.max_wr, wqe_size,66			   QUEUE_TYPE_FROM_CLIENT);67	if (!q) {68		rxe_dbg_srq(srq, "Unable to allocate queue\n");69		err = -ENOMEM;70		goto err_out;71	}72 73	err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata, q->buf,74			   q->buf_size, &q->ip);75	if (err) {76		rxe_dbg_srq(srq, "Unable to init mmap info for caller\n");77		goto err_free;78	}79 80	srq->rq.queue = q;81	init->attr.max_wr = srq->rq.max_wr;82 83	if (uresp) {84		if (copy_to_user(&uresp->srq_num, &srq->srq_num,85				 sizeof(uresp->srq_num))) {86			rxe_queue_cleanup(q);87			return -EFAULT;88		}89	}90 91	return 0;92 93err_free:94	vfree(q->buf);95	kfree(q);96err_out:97	return err;98}99 100int rxe_srq_chk_attr(struct rxe_dev *rxe, struct rxe_srq *srq,101		     struct ib_srq_attr *attr, enum ib_srq_attr_mask mask)102{103	if (srq->error) {104		rxe_dbg_srq(srq, "in error state\n");105		goto err1;106	}107 108	if (mask & IB_SRQ_MAX_WR) {109		if (attr->max_wr > rxe->attr.max_srq_wr) {110			rxe_dbg_srq(srq, "max_wr(%d) > max_srq_wr(%d)\n",111				attr->max_wr, rxe->attr.max_srq_wr);112			goto err1;113		}114 115		if (attr->max_wr <= 0) {116			rxe_dbg_srq(srq, "max_wr(%d) <= 0\n", attr->max_wr);117			goto err1;118		}119 120		if (srq->limit && (attr->max_wr < srq->limit)) {121			rxe_dbg_srq(srq, "max_wr (%d) < srq->limit (%d)\n",122				attr->max_wr, srq->limit);123			goto err1;124		}125 126		if (attr->max_wr < RXE_MIN_SRQ_WR)127			attr->max_wr = RXE_MIN_SRQ_WR;128	}129 130	if (mask & IB_SRQ_LIMIT) {131		if (attr->srq_limit > rxe->attr.max_srq_wr) {132			rxe_dbg_srq(srq, "srq_limit(%d) > max_srq_wr(%d)\n",133				attr->srq_limit, rxe->attr.max_srq_wr);134			goto err1;135		}136 137		if (attr->srq_limit > srq->rq.queue->buf->index_mask) {138			rxe_dbg_srq(srq, "srq_limit (%d) > cur limit(%d)\n",139				attr->srq_limit,140				srq->rq.queue->buf->index_mask);141			goto err1;142		}143	}144 145	return 0;146 147err1:148	return -EINVAL;149}150 151int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,152		      struct ib_srq_attr *attr, enum ib_srq_attr_mask mask,153		      struct rxe_modify_srq_cmd *ucmd, struct ib_udata *udata)154{155	struct rxe_queue *q = srq->rq.queue;156	struct mminfo __user *mi = NULL;157	int wqe_size;158	int err;159 160	if (mask & IB_SRQ_MAX_WR) {161		/*162		 * This is completely screwed up, the response is supposed to163		 * be in the outbuf not like this.164		 */165		mi = u64_to_user_ptr(ucmd->mmap_info_addr);166 167		wqe_size = sizeof(struct rxe_recv_wqe) +168				srq->rq.max_sge*sizeof(struct ib_sge);169 170		err = rxe_queue_resize(q, &attr->max_wr, wqe_size,171				       udata, mi, &srq->rq.producer_lock,172				       &srq->rq.consumer_lock);173		if (err)174			goto err_free;175 176		srq->rq.max_wr = attr->max_wr;177	}178 179	if (mask & IB_SRQ_LIMIT)180		srq->limit = attr->srq_limit;181 182	return 0;183 184err_free:185	rxe_queue_cleanup(q);186	srq->rq.queue = NULL;187	return err;188}189 190void rxe_srq_cleanup(struct rxe_pool_elem *elem)191{192	struct rxe_srq *srq = container_of(elem, typeof(*srq), elem);193 194	if (srq->pd)195		rxe_put(srq->pd);196 197	if (srq->rq.queue)198		rxe_queue_cleanup(srq->rq.queue);199}200