xref: /openbmc/linux/drivers/nvme/target/rdma.c (revision 8f000cac6e7a6edca7ab93bafc7ed28b27c1545b)
1*8f000cacSChristoph Hellwig /*
2*8f000cacSChristoph Hellwig  * NVMe over Fabrics RDMA target.
3*8f000cacSChristoph Hellwig  * Copyright (c) 2015-2016 HGST, a Western Digital Company.
4*8f000cacSChristoph Hellwig  *
5*8f000cacSChristoph Hellwig  * This program is free software; you can redistribute it and/or modify it
6*8f000cacSChristoph Hellwig  * under the terms and conditions of the GNU General Public License,
7*8f000cacSChristoph Hellwig  * version 2, as published by the Free Software Foundation.
8*8f000cacSChristoph Hellwig  *
9*8f000cacSChristoph Hellwig  * This program is distributed in the hope it will be useful, but WITHOUT
10*8f000cacSChristoph Hellwig  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*8f000cacSChristoph Hellwig  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12*8f000cacSChristoph Hellwig  * more details.
13*8f000cacSChristoph Hellwig  */
14*8f000cacSChristoph Hellwig #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15*8f000cacSChristoph Hellwig #include <linux/atomic.h>
16*8f000cacSChristoph Hellwig #include <linux/ctype.h>
17*8f000cacSChristoph Hellwig #include <linux/delay.h>
18*8f000cacSChristoph Hellwig #include <linux/err.h>
19*8f000cacSChristoph Hellwig #include <linux/init.h>
20*8f000cacSChristoph Hellwig #include <linux/module.h>
21*8f000cacSChristoph Hellwig #include <linux/nvme.h>
22*8f000cacSChristoph Hellwig #include <linux/slab.h>
23*8f000cacSChristoph Hellwig #include <linux/string.h>
24*8f000cacSChristoph Hellwig #include <linux/wait.h>
25*8f000cacSChristoph Hellwig #include <linux/inet.h>
26*8f000cacSChristoph Hellwig #include <asm/unaligned.h>
27*8f000cacSChristoph Hellwig 
28*8f000cacSChristoph Hellwig #include <rdma/ib_verbs.h>
29*8f000cacSChristoph Hellwig #include <rdma/rdma_cm.h>
30*8f000cacSChristoph Hellwig #include <rdma/rw.h>
31*8f000cacSChristoph Hellwig 
32*8f000cacSChristoph Hellwig #include <linux/nvme-rdma.h>
33*8f000cacSChristoph Hellwig #include "nvmet.h"
34*8f000cacSChristoph Hellwig 
35*8f000cacSChristoph Hellwig /*
36*8f000cacSChristoph Hellwig  * We allow up to a page of inline data to go with the SQE
37*8f000cacSChristoph Hellwig  */
38*8f000cacSChristoph Hellwig #define NVMET_RDMA_INLINE_DATA_SIZE	PAGE_SIZE
39*8f000cacSChristoph Hellwig 
40*8f000cacSChristoph Hellwig struct nvmet_rdma_cmd {
41*8f000cacSChristoph Hellwig 	struct ib_sge		sge[2];
42*8f000cacSChristoph Hellwig 	struct ib_cqe		cqe;
43*8f000cacSChristoph Hellwig 	struct ib_recv_wr	wr;
44*8f000cacSChristoph Hellwig 	struct scatterlist	inline_sg;
45*8f000cacSChristoph Hellwig 	struct page		*inline_page;
46*8f000cacSChristoph Hellwig 	struct nvme_command     *nvme_cmd;
47*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue	*queue;
48*8f000cacSChristoph Hellwig };
49*8f000cacSChristoph Hellwig 
50*8f000cacSChristoph Hellwig enum {
51*8f000cacSChristoph Hellwig 	NVMET_RDMA_REQ_INLINE_DATA	= (1 << 0),
52*8f000cacSChristoph Hellwig 	NVMET_RDMA_REQ_INVALIDATE_RKEY	= (1 << 1),
53*8f000cacSChristoph Hellwig };
54*8f000cacSChristoph Hellwig 
55*8f000cacSChristoph Hellwig struct nvmet_rdma_rsp {
56*8f000cacSChristoph Hellwig 	struct ib_sge		send_sge;
57*8f000cacSChristoph Hellwig 	struct ib_cqe		send_cqe;
58*8f000cacSChristoph Hellwig 	struct ib_send_wr	send_wr;
59*8f000cacSChristoph Hellwig 
60*8f000cacSChristoph Hellwig 	struct nvmet_rdma_cmd	*cmd;
61*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue	*queue;
62*8f000cacSChristoph Hellwig 
63*8f000cacSChristoph Hellwig 	struct ib_cqe		read_cqe;
64*8f000cacSChristoph Hellwig 	struct rdma_rw_ctx	rw;
65*8f000cacSChristoph Hellwig 
66*8f000cacSChristoph Hellwig 	struct nvmet_req	req;
67*8f000cacSChristoph Hellwig 
68*8f000cacSChristoph Hellwig 	u8			n_rdma;
69*8f000cacSChristoph Hellwig 	u32			flags;
70*8f000cacSChristoph Hellwig 	u32			invalidate_rkey;
71*8f000cacSChristoph Hellwig 
72*8f000cacSChristoph Hellwig 	struct list_head	wait_list;
73*8f000cacSChristoph Hellwig 	struct list_head	free_list;
74*8f000cacSChristoph Hellwig };
75*8f000cacSChristoph Hellwig 
76*8f000cacSChristoph Hellwig enum nvmet_rdma_queue_state {
77*8f000cacSChristoph Hellwig 	NVMET_RDMA_Q_CONNECTING,
78*8f000cacSChristoph Hellwig 	NVMET_RDMA_Q_LIVE,
79*8f000cacSChristoph Hellwig 	NVMET_RDMA_Q_DISCONNECTING,
80*8f000cacSChristoph Hellwig };
81*8f000cacSChristoph Hellwig 
82*8f000cacSChristoph Hellwig struct nvmet_rdma_queue {
83*8f000cacSChristoph Hellwig 	struct rdma_cm_id	*cm_id;
84*8f000cacSChristoph Hellwig 	struct nvmet_port	*port;
85*8f000cacSChristoph Hellwig 	struct ib_cq		*cq;
86*8f000cacSChristoph Hellwig 	atomic_t		sq_wr_avail;
87*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *dev;
88*8f000cacSChristoph Hellwig 	spinlock_t		state_lock;
89*8f000cacSChristoph Hellwig 	enum nvmet_rdma_queue_state state;
90*8f000cacSChristoph Hellwig 	struct nvmet_cq		nvme_cq;
91*8f000cacSChristoph Hellwig 	struct nvmet_sq		nvme_sq;
92*8f000cacSChristoph Hellwig 
93*8f000cacSChristoph Hellwig 	struct nvmet_rdma_rsp	*rsps;
94*8f000cacSChristoph Hellwig 	struct list_head	free_rsps;
95*8f000cacSChristoph Hellwig 	spinlock_t		rsps_lock;
96*8f000cacSChristoph Hellwig 	struct nvmet_rdma_cmd	*cmds;
97*8f000cacSChristoph Hellwig 
98*8f000cacSChristoph Hellwig 	struct work_struct	release_work;
99*8f000cacSChristoph Hellwig 	struct list_head	rsp_wait_list;
100*8f000cacSChristoph Hellwig 	struct list_head	rsp_wr_wait_list;
101*8f000cacSChristoph Hellwig 	spinlock_t		rsp_wr_wait_lock;
102*8f000cacSChristoph Hellwig 
103*8f000cacSChristoph Hellwig 	int			idx;
104*8f000cacSChristoph Hellwig 	int			host_qid;
105*8f000cacSChristoph Hellwig 	int			recv_queue_size;
106*8f000cacSChristoph Hellwig 	int			send_queue_size;
107*8f000cacSChristoph Hellwig 
108*8f000cacSChristoph Hellwig 	struct list_head	queue_list;
109*8f000cacSChristoph Hellwig };
110*8f000cacSChristoph Hellwig 
111*8f000cacSChristoph Hellwig struct nvmet_rdma_device {
112*8f000cacSChristoph Hellwig 	struct ib_device	*device;
113*8f000cacSChristoph Hellwig 	struct ib_pd		*pd;
114*8f000cacSChristoph Hellwig 	struct ib_srq		*srq;
115*8f000cacSChristoph Hellwig 	struct nvmet_rdma_cmd	*srq_cmds;
116*8f000cacSChristoph Hellwig 	size_t			srq_size;
117*8f000cacSChristoph Hellwig 	struct kref		ref;
118*8f000cacSChristoph Hellwig 	struct list_head	entry;
119*8f000cacSChristoph Hellwig };
120*8f000cacSChristoph Hellwig 
121*8f000cacSChristoph Hellwig static bool nvmet_rdma_use_srq;
122*8f000cacSChristoph Hellwig module_param_named(use_srq, nvmet_rdma_use_srq, bool, 0444);
123*8f000cacSChristoph Hellwig MODULE_PARM_DESC(use_srq, "Use shared receive queue.");
124*8f000cacSChristoph Hellwig 
125*8f000cacSChristoph Hellwig static DEFINE_IDA(nvmet_rdma_queue_ida);
126*8f000cacSChristoph Hellwig static LIST_HEAD(nvmet_rdma_queue_list);
127*8f000cacSChristoph Hellwig static DEFINE_MUTEX(nvmet_rdma_queue_mutex);
128*8f000cacSChristoph Hellwig 
129*8f000cacSChristoph Hellwig static LIST_HEAD(device_list);
130*8f000cacSChristoph Hellwig static DEFINE_MUTEX(device_list_mutex);
131*8f000cacSChristoph Hellwig 
132*8f000cacSChristoph Hellwig static bool nvmet_rdma_execute_command(struct nvmet_rdma_rsp *rsp);
133*8f000cacSChristoph Hellwig static void nvmet_rdma_send_done(struct ib_cq *cq, struct ib_wc *wc);
134*8f000cacSChristoph Hellwig static void nvmet_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc);
135*8f000cacSChristoph Hellwig static void nvmet_rdma_read_data_done(struct ib_cq *cq, struct ib_wc *wc);
136*8f000cacSChristoph Hellwig static void nvmet_rdma_qp_event(struct ib_event *event, void *priv);
137*8f000cacSChristoph Hellwig static void nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue);
138*8f000cacSChristoph Hellwig 
139*8f000cacSChristoph Hellwig static struct nvmet_fabrics_ops nvmet_rdma_ops;
140*8f000cacSChristoph Hellwig 
141*8f000cacSChristoph Hellwig /* XXX: really should move to a generic header sooner or later.. */
142*8f000cacSChristoph Hellwig static inline u32 get_unaligned_le24(const u8 *p)
143*8f000cacSChristoph Hellwig {
144*8f000cacSChristoph Hellwig 	return (u32)p[0] | (u32)p[1] << 8 | (u32)p[2] << 16;
145*8f000cacSChristoph Hellwig }
146*8f000cacSChristoph Hellwig 
147*8f000cacSChristoph Hellwig static inline bool nvmet_rdma_need_data_in(struct nvmet_rdma_rsp *rsp)
148*8f000cacSChristoph Hellwig {
149*8f000cacSChristoph Hellwig 	return nvme_is_write(rsp->req.cmd) &&
150*8f000cacSChristoph Hellwig 		rsp->req.data_len &&
151*8f000cacSChristoph Hellwig 		!(rsp->flags & NVMET_RDMA_REQ_INLINE_DATA);
152*8f000cacSChristoph Hellwig }
153*8f000cacSChristoph Hellwig 
154*8f000cacSChristoph Hellwig static inline bool nvmet_rdma_need_data_out(struct nvmet_rdma_rsp *rsp)
155*8f000cacSChristoph Hellwig {
156*8f000cacSChristoph Hellwig 	return !nvme_is_write(rsp->req.cmd) &&
157*8f000cacSChristoph Hellwig 		rsp->req.data_len &&
158*8f000cacSChristoph Hellwig 		!rsp->req.rsp->status &&
159*8f000cacSChristoph Hellwig 		!(rsp->flags & NVMET_RDMA_REQ_INLINE_DATA);
160*8f000cacSChristoph Hellwig }
161*8f000cacSChristoph Hellwig 
162*8f000cacSChristoph Hellwig static inline struct nvmet_rdma_rsp *
163*8f000cacSChristoph Hellwig nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
164*8f000cacSChristoph Hellwig {
165*8f000cacSChristoph Hellwig 	struct nvmet_rdma_rsp *rsp;
166*8f000cacSChristoph Hellwig 	unsigned long flags;
167*8f000cacSChristoph Hellwig 
168*8f000cacSChristoph Hellwig 	spin_lock_irqsave(&queue->rsps_lock, flags);
169*8f000cacSChristoph Hellwig 	rsp = list_first_entry(&queue->free_rsps,
170*8f000cacSChristoph Hellwig 				struct nvmet_rdma_rsp, free_list);
171*8f000cacSChristoph Hellwig 	list_del(&rsp->free_list);
172*8f000cacSChristoph Hellwig 	spin_unlock_irqrestore(&queue->rsps_lock, flags);
173*8f000cacSChristoph Hellwig 
174*8f000cacSChristoph Hellwig 	return rsp;
175*8f000cacSChristoph Hellwig }
176*8f000cacSChristoph Hellwig 
177*8f000cacSChristoph Hellwig static inline void
178*8f000cacSChristoph Hellwig nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp)
179*8f000cacSChristoph Hellwig {
180*8f000cacSChristoph Hellwig 	unsigned long flags;
181*8f000cacSChristoph Hellwig 
182*8f000cacSChristoph Hellwig 	spin_lock_irqsave(&rsp->queue->rsps_lock, flags);
183*8f000cacSChristoph Hellwig 	list_add_tail(&rsp->free_list, &rsp->queue->free_rsps);
184*8f000cacSChristoph Hellwig 	spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags);
185*8f000cacSChristoph Hellwig }
186*8f000cacSChristoph Hellwig 
187*8f000cacSChristoph Hellwig static void nvmet_rdma_free_sgl(struct scatterlist *sgl, unsigned int nents)
188*8f000cacSChristoph Hellwig {
189*8f000cacSChristoph Hellwig 	struct scatterlist *sg;
190*8f000cacSChristoph Hellwig 	int count;
191*8f000cacSChristoph Hellwig 
192*8f000cacSChristoph Hellwig 	if (!sgl || !nents)
193*8f000cacSChristoph Hellwig 		return;
194*8f000cacSChristoph Hellwig 
195*8f000cacSChristoph Hellwig 	for_each_sg(sgl, sg, nents, count)
196*8f000cacSChristoph Hellwig 		__free_page(sg_page(sg));
197*8f000cacSChristoph Hellwig 	kfree(sgl);
198*8f000cacSChristoph Hellwig }
199*8f000cacSChristoph Hellwig 
200*8f000cacSChristoph Hellwig static int nvmet_rdma_alloc_sgl(struct scatterlist **sgl, unsigned int *nents,
201*8f000cacSChristoph Hellwig 		u32 length)
202*8f000cacSChristoph Hellwig {
203*8f000cacSChristoph Hellwig 	struct scatterlist *sg;
204*8f000cacSChristoph Hellwig 	struct page *page;
205*8f000cacSChristoph Hellwig 	unsigned int nent;
206*8f000cacSChristoph Hellwig 	int i = 0;
207*8f000cacSChristoph Hellwig 
208*8f000cacSChristoph Hellwig 	nent = DIV_ROUND_UP(length, PAGE_SIZE);
209*8f000cacSChristoph Hellwig 	sg = kmalloc_array(nent, sizeof(struct scatterlist), GFP_KERNEL);
210*8f000cacSChristoph Hellwig 	if (!sg)
211*8f000cacSChristoph Hellwig 		goto out;
212*8f000cacSChristoph Hellwig 
213*8f000cacSChristoph Hellwig 	sg_init_table(sg, nent);
214*8f000cacSChristoph Hellwig 
215*8f000cacSChristoph Hellwig 	while (length) {
216*8f000cacSChristoph Hellwig 		u32 page_len = min_t(u32, length, PAGE_SIZE);
217*8f000cacSChristoph Hellwig 
218*8f000cacSChristoph Hellwig 		page = alloc_page(GFP_KERNEL);
219*8f000cacSChristoph Hellwig 		if (!page)
220*8f000cacSChristoph Hellwig 			goto out_free_pages;
221*8f000cacSChristoph Hellwig 
222*8f000cacSChristoph Hellwig 		sg_set_page(&sg[i], page, page_len, 0);
223*8f000cacSChristoph Hellwig 		length -= page_len;
224*8f000cacSChristoph Hellwig 		i++;
225*8f000cacSChristoph Hellwig 	}
226*8f000cacSChristoph Hellwig 	*sgl = sg;
227*8f000cacSChristoph Hellwig 	*nents = nent;
228*8f000cacSChristoph Hellwig 	return 0;
229*8f000cacSChristoph Hellwig 
230*8f000cacSChristoph Hellwig out_free_pages:
231*8f000cacSChristoph Hellwig 	while (i > 0) {
232*8f000cacSChristoph Hellwig 		i--;
233*8f000cacSChristoph Hellwig 		__free_page(sg_page(&sg[i]));
234*8f000cacSChristoph Hellwig 	}
235*8f000cacSChristoph Hellwig 	kfree(sg);
236*8f000cacSChristoph Hellwig out:
237*8f000cacSChristoph Hellwig 	return NVME_SC_INTERNAL;
238*8f000cacSChristoph Hellwig }
239*8f000cacSChristoph Hellwig 
240*8f000cacSChristoph Hellwig static int nvmet_rdma_alloc_cmd(struct nvmet_rdma_device *ndev,
241*8f000cacSChristoph Hellwig 			struct nvmet_rdma_cmd *c, bool admin)
242*8f000cacSChristoph Hellwig {
243*8f000cacSChristoph Hellwig 	/* NVMe command / RDMA RECV */
244*8f000cacSChristoph Hellwig 	c->nvme_cmd = kmalloc(sizeof(*c->nvme_cmd), GFP_KERNEL);
245*8f000cacSChristoph Hellwig 	if (!c->nvme_cmd)
246*8f000cacSChristoph Hellwig 		goto out;
247*8f000cacSChristoph Hellwig 
248*8f000cacSChristoph Hellwig 	c->sge[0].addr = ib_dma_map_single(ndev->device, c->nvme_cmd,
249*8f000cacSChristoph Hellwig 			sizeof(*c->nvme_cmd), DMA_FROM_DEVICE);
250*8f000cacSChristoph Hellwig 	if (ib_dma_mapping_error(ndev->device, c->sge[0].addr))
251*8f000cacSChristoph Hellwig 		goto out_free_cmd;
252*8f000cacSChristoph Hellwig 
253*8f000cacSChristoph Hellwig 	c->sge[0].length = sizeof(*c->nvme_cmd);
254*8f000cacSChristoph Hellwig 	c->sge[0].lkey = ndev->pd->local_dma_lkey;
255*8f000cacSChristoph Hellwig 
256*8f000cacSChristoph Hellwig 	if (!admin) {
257*8f000cacSChristoph Hellwig 		c->inline_page = alloc_pages(GFP_KERNEL,
258*8f000cacSChristoph Hellwig 				get_order(NVMET_RDMA_INLINE_DATA_SIZE));
259*8f000cacSChristoph Hellwig 		if (!c->inline_page)
260*8f000cacSChristoph Hellwig 			goto out_unmap_cmd;
261*8f000cacSChristoph Hellwig 		c->sge[1].addr = ib_dma_map_page(ndev->device,
262*8f000cacSChristoph Hellwig 				c->inline_page, 0, NVMET_RDMA_INLINE_DATA_SIZE,
263*8f000cacSChristoph Hellwig 				DMA_FROM_DEVICE);
264*8f000cacSChristoph Hellwig 		if (ib_dma_mapping_error(ndev->device, c->sge[1].addr))
265*8f000cacSChristoph Hellwig 			goto out_free_inline_page;
266*8f000cacSChristoph Hellwig 		c->sge[1].length = NVMET_RDMA_INLINE_DATA_SIZE;
267*8f000cacSChristoph Hellwig 		c->sge[1].lkey = ndev->pd->local_dma_lkey;
268*8f000cacSChristoph Hellwig 	}
269*8f000cacSChristoph Hellwig 
270*8f000cacSChristoph Hellwig 	c->cqe.done = nvmet_rdma_recv_done;
271*8f000cacSChristoph Hellwig 
272*8f000cacSChristoph Hellwig 	c->wr.wr_cqe = &c->cqe;
273*8f000cacSChristoph Hellwig 	c->wr.sg_list = c->sge;
274*8f000cacSChristoph Hellwig 	c->wr.num_sge = admin ? 1 : 2;
275*8f000cacSChristoph Hellwig 
276*8f000cacSChristoph Hellwig 	return 0;
277*8f000cacSChristoph Hellwig 
278*8f000cacSChristoph Hellwig out_free_inline_page:
279*8f000cacSChristoph Hellwig 	if (!admin) {
280*8f000cacSChristoph Hellwig 		__free_pages(c->inline_page,
281*8f000cacSChristoph Hellwig 				get_order(NVMET_RDMA_INLINE_DATA_SIZE));
282*8f000cacSChristoph Hellwig 	}
283*8f000cacSChristoph Hellwig out_unmap_cmd:
284*8f000cacSChristoph Hellwig 	ib_dma_unmap_single(ndev->device, c->sge[0].addr,
285*8f000cacSChristoph Hellwig 			sizeof(*c->nvme_cmd), DMA_FROM_DEVICE);
286*8f000cacSChristoph Hellwig out_free_cmd:
287*8f000cacSChristoph Hellwig 	kfree(c->nvme_cmd);
288*8f000cacSChristoph Hellwig 
289*8f000cacSChristoph Hellwig out:
290*8f000cacSChristoph Hellwig 	return -ENOMEM;
291*8f000cacSChristoph Hellwig }
292*8f000cacSChristoph Hellwig 
293*8f000cacSChristoph Hellwig static void nvmet_rdma_free_cmd(struct nvmet_rdma_device *ndev,
294*8f000cacSChristoph Hellwig 		struct nvmet_rdma_cmd *c, bool admin)
295*8f000cacSChristoph Hellwig {
296*8f000cacSChristoph Hellwig 	if (!admin) {
297*8f000cacSChristoph Hellwig 		ib_dma_unmap_page(ndev->device, c->sge[1].addr,
298*8f000cacSChristoph Hellwig 				NVMET_RDMA_INLINE_DATA_SIZE, DMA_FROM_DEVICE);
299*8f000cacSChristoph Hellwig 		__free_pages(c->inline_page,
300*8f000cacSChristoph Hellwig 				get_order(NVMET_RDMA_INLINE_DATA_SIZE));
301*8f000cacSChristoph Hellwig 	}
302*8f000cacSChristoph Hellwig 	ib_dma_unmap_single(ndev->device, c->sge[0].addr,
303*8f000cacSChristoph Hellwig 				sizeof(*c->nvme_cmd), DMA_FROM_DEVICE);
304*8f000cacSChristoph Hellwig 	kfree(c->nvme_cmd);
305*8f000cacSChristoph Hellwig }
306*8f000cacSChristoph Hellwig 
307*8f000cacSChristoph Hellwig static struct nvmet_rdma_cmd *
308*8f000cacSChristoph Hellwig nvmet_rdma_alloc_cmds(struct nvmet_rdma_device *ndev,
309*8f000cacSChristoph Hellwig 		int nr_cmds, bool admin)
310*8f000cacSChristoph Hellwig {
311*8f000cacSChristoph Hellwig 	struct nvmet_rdma_cmd *cmds;
312*8f000cacSChristoph Hellwig 	int ret = -EINVAL, i;
313*8f000cacSChristoph Hellwig 
314*8f000cacSChristoph Hellwig 	cmds = kcalloc(nr_cmds, sizeof(struct nvmet_rdma_cmd), GFP_KERNEL);
315*8f000cacSChristoph Hellwig 	if (!cmds)
316*8f000cacSChristoph Hellwig 		goto out;
317*8f000cacSChristoph Hellwig 
318*8f000cacSChristoph Hellwig 	for (i = 0; i < nr_cmds; i++) {
319*8f000cacSChristoph Hellwig 		ret = nvmet_rdma_alloc_cmd(ndev, cmds + i, admin);
320*8f000cacSChristoph Hellwig 		if (ret)
321*8f000cacSChristoph Hellwig 			goto out_free;
322*8f000cacSChristoph Hellwig 	}
323*8f000cacSChristoph Hellwig 
324*8f000cacSChristoph Hellwig 	return cmds;
325*8f000cacSChristoph Hellwig 
326*8f000cacSChristoph Hellwig out_free:
327*8f000cacSChristoph Hellwig 	while (--i >= 0)
328*8f000cacSChristoph Hellwig 		nvmet_rdma_free_cmd(ndev, cmds + i, admin);
329*8f000cacSChristoph Hellwig 	kfree(cmds);
330*8f000cacSChristoph Hellwig out:
331*8f000cacSChristoph Hellwig 	return ERR_PTR(ret);
332*8f000cacSChristoph Hellwig }
333*8f000cacSChristoph Hellwig 
334*8f000cacSChristoph Hellwig static void nvmet_rdma_free_cmds(struct nvmet_rdma_device *ndev,
335*8f000cacSChristoph Hellwig 		struct nvmet_rdma_cmd *cmds, int nr_cmds, bool admin)
336*8f000cacSChristoph Hellwig {
337*8f000cacSChristoph Hellwig 	int i;
338*8f000cacSChristoph Hellwig 
339*8f000cacSChristoph Hellwig 	for (i = 0; i < nr_cmds; i++)
340*8f000cacSChristoph Hellwig 		nvmet_rdma_free_cmd(ndev, cmds + i, admin);
341*8f000cacSChristoph Hellwig 	kfree(cmds);
342*8f000cacSChristoph Hellwig }
343*8f000cacSChristoph Hellwig 
344*8f000cacSChristoph Hellwig static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev,
345*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *r)
346*8f000cacSChristoph Hellwig {
347*8f000cacSChristoph Hellwig 	/* NVMe CQE / RDMA SEND */
348*8f000cacSChristoph Hellwig 	r->req.rsp = kmalloc(sizeof(*r->req.rsp), GFP_KERNEL);
349*8f000cacSChristoph Hellwig 	if (!r->req.rsp)
350*8f000cacSChristoph Hellwig 		goto out;
351*8f000cacSChristoph Hellwig 
352*8f000cacSChristoph Hellwig 	r->send_sge.addr = ib_dma_map_single(ndev->device, r->req.rsp,
353*8f000cacSChristoph Hellwig 			sizeof(*r->req.rsp), DMA_TO_DEVICE);
354*8f000cacSChristoph Hellwig 	if (ib_dma_mapping_error(ndev->device, r->send_sge.addr))
355*8f000cacSChristoph Hellwig 		goto out_free_rsp;
356*8f000cacSChristoph Hellwig 
357*8f000cacSChristoph Hellwig 	r->send_sge.length = sizeof(*r->req.rsp);
358*8f000cacSChristoph Hellwig 	r->send_sge.lkey = ndev->pd->local_dma_lkey;
359*8f000cacSChristoph Hellwig 
360*8f000cacSChristoph Hellwig 	r->send_cqe.done = nvmet_rdma_send_done;
361*8f000cacSChristoph Hellwig 
362*8f000cacSChristoph Hellwig 	r->send_wr.wr_cqe = &r->send_cqe;
363*8f000cacSChristoph Hellwig 	r->send_wr.sg_list = &r->send_sge;
364*8f000cacSChristoph Hellwig 	r->send_wr.num_sge = 1;
365*8f000cacSChristoph Hellwig 	r->send_wr.send_flags = IB_SEND_SIGNALED;
366*8f000cacSChristoph Hellwig 
367*8f000cacSChristoph Hellwig 	/* Data In / RDMA READ */
368*8f000cacSChristoph Hellwig 	r->read_cqe.done = nvmet_rdma_read_data_done;
369*8f000cacSChristoph Hellwig 	return 0;
370*8f000cacSChristoph Hellwig 
371*8f000cacSChristoph Hellwig out_free_rsp:
372*8f000cacSChristoph Hellwig 	kfree(r->req.rsp);
373*8f000cacSChristoph Hellwig out:
374*8f000cacSChristoph Hellwig 	return -ENOMEM;
375*8f000cacSChristoph Hellwig }
376*8f000cacSChristoph Hellwig 
377*8f000cacSChristoph Hellwig static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev,
378*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *r)
379*8f000cacSChristoph Hellwig {
380*8f000cacSChristoph Hellwig 	ib_dma_unmap_single(ndev->device, r->send_sge.addr,
381*8f000cacSChristoph Hellwig 				sizeof(*r->req.rsp), DMA_TO_DEVICE);
382*8f000cacSChristoph Hellwig 	kfree(r->req.rsp);
383*8f000cacSChristoph Hellwig }
384*8f000cacSChristoph Hellwig 
385*8f000cacSChristoph Hellwig static int
386*8f000cacSChristoph Hellwig nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue)
387*8f000cacSChristoph Hellwig {
388*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *ndev = queue->dev;
389*8f000cacSChristoph Hellwig 	int nr_rsps = queue->recv_queue_size * 2;
390*8f000cacSChristoph Hellwig 	int ret = -EINVAL, i;
391*8f000cacSChristoph Hellwig 
392*8f000cacSChristoph Hellwig 	queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp),
393*8f000cacSChristoph Hellwig 			GFP_KERNEL);
394*8f000cacSChristoph Hellwig 	if (!queue->rsps)
395*8f000cacSChristoph Hellwig 		goto out;
396*8f000cacSChristoph Hellwig 
397*8f000cacSChristoph Hellwig 	for (i = 0; i < nr_rsps; i++) {
398*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
399*8f000cacSChristoph Hellwig 
400*8f000cacSChristoph Hellwig 		ret = nvmet_rdma_alloc_rsp(ndev, rsp);
401*8f000cacSChristoph Hellwig 		if (ret)
402*8f000cacSChristoph Hellwig 			goto out_free;
403*8f000cacSChristoph Hellwig 
404*8f000cacSChristoph Hellwig 		list_add_tail(&rsp->free_list, &queue->free_rsps);
405*8f000cacSChristoph Hellwig 	}
406*8f000cacSChristoph Hellwig 
407*8f000cacSChristoph Hellwig 	return 0;
408*8f000cacSChristoph Hellwig 
409*8f000cacSChristoph Hellwig out_free:
410*8f000cacSChristoph Hellwig 	while (--i >= 0) {
411*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
412*8f000cacSChristoph Hellwig 
413*8f000cacSChristoph Hellwig 		list_del(&rsp->free_list);
414*8f000cacSChristoph Hellwig 		nvmet_rdma_free_rsp(ndev, rsp);
415*8f000cacSChristoph Hellwig 	}
416*8f000cacSChristoph Hellwig 	kfree(queue->rsps);
417*8f000cacSChristoph Hellwig out:
418*8f000cacSChristoph Hellwig 	return ret;
419*8f000cacSChristoph Hellwig }
420*8f000cacSChristoph Hellwig 
421*8f000cacSChristoph Hellwig static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue)
422*8f000cacSChristoph Hellwig {
423*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *ndev = queue->dev;
424*8f000cacSChristoph Hellwig 	int i, nr_rsps = queue->recv_queue_size * 2;
425*8f000cacSChristoph Hellwig 
426*8f000cacSChristoph Hellwig 	for (i = 0; i < nr_rsps; i++) {
427*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
428*8f000cacSChristoph Hellwig 
429*8f000cacSChristoph Hellwig 		list_del(&rsp->free_list);
430*8f000cacSChristoph Hellwig 		nvmet_rdma_free_rsp(ndev, rsp);
431*8f000cacSChristoph Hellwig 	}
432*8f000cacSChristoph Hellwig 	kfree(queue->rsps);
433*8f000cacSChristoph Hellwig }
434*8f000cacSChristoph Hellwig 
435*8f000cacSChristoph Hellwig static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev,
436*8f000cacSChristoph Hellwig 		struct nvmet_rdma_cmd *cmd)
437*8f000cacSChristoph Hellwig {
438*8f000cacSChristoph Hellwig 	struct ib_recv_wr *bad_wr;
439*8f000cacSChristoph Hellwig 
440*8f000cacSChristoph Hellwig 	if (ndev->srq)
441*8f000cacSChristoph Hellwig 		return ib_post_srq_recv(ndev->srq, &cmd->wr, &bad_wr);
442*8f000cacSChristoph Hellwig 	return ib_post_recv(cmd->queue->cm_id->qp, &cmd->wr, &bad_wr);
443*8f000cacSChristoph Hellwig }
444*8f000cacSChristoph Hellwig 
445*8f000cacSChristoph Hellwig static void nvmet_rdma_process_wr_wait_list(struct nvmet_rdma_queue *queue)
446*8f000cacSChristoph Hellwig {
447*8f000cacSChristoph Hellwig 	spin_lock(&queue->rsp_wr_wait_lock);
448*8f000cacSChristoph Hellwig 	while (!list_empty(&queue->rsp_wr_wait_list)) {
449*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *rsp;
450*8f000cacSChristoph Hellwig 		bool ret;
451*8f000cacSChristoph Hellwig 
452*8f000cacSChristoph Hellwig 		rsp = list_entry(queue->rsp_wr_wait_list.next,
453*8f000cacSChristoph Hellwig 				struct nvmet_rdma_rsp, wait_list);
454*8f000cacSChristoph Hellwig 		list_del(&rsp->wait_list);
455*8f000cacSChristoph Hellwig 
456*8f000cacSChristoph Hellwig 		spin_unlock(&queue->rsp_wr_wait_lock);
457*8f000cacSChristoph Hellwig 		ret = nvmet_rdma_execute_command(rsp);
458*8f000cacSChristoph Hellwig 		spin_lock(&queue->rsp_wr_wait_lock);
459*8f000cacSChristoph Hellwig 
460*8f000cacSChristoph Hellwig 		if (!ret) {
461*8f000cacSChristoph Hellwig 			list_add(&rsp->wait_list, &queue->rsp_wr_wait_list);
462*8f000cacSChristoph Hellwig 			break;
463*8f000cacSChristoph Hellwig 		}
464*8f000cacSChristoph Hellwig 	}
465*8f000cacSChristoph Hellwig 	spin_unlock(&queue->rsp_wr_wait_lock);
466*8f000cacSChristoph Hellwig }
467*8f000cacSChristoph Hellwig 
468*8f000cacSChristoph Hellwig 
469*8f000cacSChristoph Hellwig static void nvmet_rdma_release_rsp(struct nvmet_rdma_rsp *rsp)
470*8f000cacSChristoph Hellwig {
471*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue = rsp->queue;
472*8f000cacSChristoph Hellwig 
473*8f000cacSChristoph Hellwig 	atomic_add(1 + rsp->n_rdma, &queue->sq_wr_avail);
474*8f000cacSChristoph Hellwig 
475*8f000cacSChristoph Hellwig 	if (rsp->n_rdma) {
476*8f000cacSChristoph Hellwig 		rdma_rw_ctx_destroy(&rsp->rw, queue->cm_id->qp,
477*8f000cacSChristoph Hellwig 				queue->cm_id->port_num, rsp->req.sg,
478*8f000cacSChristoph Hellwig 				rsp->req.sg_cnt, nvmet_data_dir(&rsp->req));
479*8f000cacSChristoph Hellwig 	}
480*8f000cacSChristoph Hellwig 
481*8f000cacSChristoph Hellwig 	if (rsp->req.sg != &rsp->cmd->inline_sg)
482*8f000cacSChristoph Hellwig 		nvmet_rdma_free_sgl(rsp->req.sg, rsp->req.sg_cnt);
483*8f000cacSChristoph Hellwig 
484*8f000cacSChristoph Hellwig 	if (unlikely(!list_empty_careful(&queue->rsp_wr_wait_list)))
485*8f000cacSChristoph Hellwig 		nvmet_rdma_process_wr_wait_list(queue);
486*8f000cacSChristoph Hellwig 
487*8f000cacSChristoph Hellwig 	nvmet_rdma_put_rsp(rsp);
488*8f000cacSChristoph Hellwig }
489*8f000cacSChristoph Hellwig 
490*8f000cacSChristoph Hellwig static void nvmet_rdma_error_comp(struct nvmet_rdma_queue *queue)
491*8f000cacSChristoph Hellwig {
492*8f000cacSChristoph Hellwig 	if (queue->nvme_sq.ctrl) {
493*8f000cacSChristoph Hellwig 		nvmet_ctrl_fatal_error(queue->nvme_sq.ctrl);
494*8f000cacSChristoph Hellwig 	} else {
495*8f000cacSChristoph Hellwig 		/*
496*8f000cacSChristoph Hellwig 		 * we didn't setup the controller yet in case
497*8f000cacSChristoph Hellwig 		 * of admin connect error, just disconnect and
498*8f000cacSChristoph Hellwig 		 * cleanup the queue
499*8f000cacSChristoph Hellwig 		 */
500*8f000cacSChristoph Hellwig 		nvmet_rdma_queue_disconnect(queue);
501*8f000cacSChristoph Hellwig 	}
502*8f000cacSChristoph Hellwig }
503*8f000cacSChristoph Hellwig 
504*8f000cacSChristoph Hellwig static void nvmet_rdma_send_done(struct ib_cq *cq, struct ib_wc *wc)
505*8f000cacSChristoph Hellwig {
506*8f000cacSChristoph Hellwig 	struct nvmet_rdma_rsp *rsp =
507*8f000cacSChristoph Hellwig 		container_of(wc->wr_cqe, struct nvmet_rdma_rsp, send_cqe);
508*8f000cacSChristoph Hellwig 
509*8f000cacSChristoph Hellwig 	nvmet_rdma_release_rsp(rsp);
510*8f000cacSChristoph Hellwig 
511*8f000cacSChristoph Hellwig 	if (unlikely(wc->status != IB_WC_SUCCESS &&
512*8f000cacSChristoph Hellwig 		     wc->status != IB_WC_WR_FLUSH_ERR)) {
513*8f000cacSChristoph Hellwig 		pr_err("SEND for CQE 0x%p failed with status %s (%d).\n",
514*8f000cacSChristoph Hellwig 			wc->wr_cqe, ib_wc_status_msg(wc->status), wc->status);
515*8f000cacSChristoph Hellwig 		nvmet_rdma_error_comp(rsp->queue);
516*8f000cacSChristoph Hellwig 	}
517*8f000cacSChristoph Hellwig }
518*8f000cacSChristoph Hellwig 
519*8f000cacSChristoph Hellwig static void nvmet_rdma_queue_response(struct nvmet_req *req)
520*8f000cacSChristoph Hellwig {
521*8f000cacSChristoph Hellwig 	struct nvmet_rdma_rsp *rsp =
522*8f000cacSChristoph Hellwig 		container_of(req, struct nvmet_rdma_rsp, req);
523*8f000cacSChristoph Hellwig 	struct rdma_cm_id *cm_id = rsp->queue->cm_id;
524*8f000cacSChristoph Hellwig 	struct ib_send_wr *first_wr, *bad_wr;
525*8f000cacSChristoph Hellwig 
526*8f000cacSChristoph Hellwig 	if (rsp->flags & NVMET_RDMA_REQ_INVALIDATE_RKEY) {
527*8f000cacSChristoph Hellwig 		rsp->send_wr.opcode = IB_WR_SEND_WITH_INV;
528*8f000cacSChristoph Hellwig 		rsp->send_wr.ex.invalidate_rkey = rsp->invalidate_rkey;
529*8f000cacSChristoph Hellwig 	} else {
530*8f000cacSChristoph Hellwig 		rsp->send_wr.opcode = IB_WR_SEND;
531*8f000cacSChristoph Hellwig 	}
532*8f000cacSChristoph Hellwig 
533*8f000cacSChristoph Hellwig 	if (nvmet_rdma_need_data_out(rsp))
534*8f000cacSChristoph Hellwig 		first_wr = rdma_rw_ctx_wrs(&rsp->rw, cm_id->qp,
535*8f000cacSChristoph Hellwig 				cm_id->port_num, NULL, &rsp->send_wr);
536*8f000cacSChristoph Hellwig 	else
537*8f000cacSChristoph Hellwig 		first_wr = &rsp->send_wr;
538*8f000cacSChristoph Hellwig 
539*8f000cacSChristoph Hellwig 	nvmet_rdma_post_recv(rsp->queue->dev, rsp->cmd);
540*8f000cacSChristoph Hellwig 	if (ib_post_send(cm_id->qp, first_wr, &bad_wr)) {
541*8f000cacSChristoph Hellwig 		pr_err("sending cmd response failed\n");
542*8f000cacSChristoph Hellwig 		nvmet_rdma_release_rsp(rsp);
543*8f000cacSChristoph Hellwig 	}
544*8f000cacSChristoph Hellwig }
545*8f000cacSChristoph Hellwig 
546*8f000cacSChristoph Hellwig static void nvmet_rdma_read_data_done(struct ib_cq *cq, struct ib_wc *wc)
547*8f000cacSChristoph Hellwig {
548*8f000cacSChristoph Hellwig 	struct nvmet_rdma_rsp *rsp =
549*8f000cacSChristoph Hellwig 		container_of(wc->wr_cqe, struct nvmet_rdma_rsp, read_cqe);
550*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue = cq->cq_context;
551*8f000cacSChristoph Hellwig 
552*8f000cacSChristoph Hellwig 	WARN_ON(rsp->n_rdma <= 0);
553*8f000cacSChristoph Hellwig 	atomic_add(rsp->n_rdma, &queue->sq_wr_avail);
554*8f000cacSChristoph Hellwig 	rdma_rw_ctx_destroy(&rsp->rw, queue->cm_id->qp,
555*8f000cacSChristoph Hellwig 			queue->cm_id->port_num, rsp->req.sg,
556*8f000cacSChristoph Hellwig 			rsp->req.sg_cnt, nvmet_data_dir(&rsp->req));
557*8f000cacSChristoph Hellwig 	rsp->n_rdma = 0;
558*8f000cacSChristoph Hellwig 
559*8f000cacSChristoph Hellwig 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
560*8f000cacSChristoph Hellwig 		nvmet_rdma_release_rsp(rsp);
561*8f000cacSChristoph Hellwig 		if (wc->status != IB_WC_WR_FLUSH_ERR) {
562*8f000cacSChristoph Hellwig 			pr_info("RDMA READ for CQE 0x%p failed with status %s (%d).\n",
563*8f000cacSChristoph Hellwig 				wc->wr_cqe, ib_wc_status_msg(wc->status), wc->status);
564*8f000cacSChristoph Hellwig 			nvmet_rdma_error_comp(queue);
565*8f000cacSChristoph Hellwig 		}
566*8f000cacSChristoph Hellwig 		return;
567*8f000cacSChristoph Hellwig 	}
568*8f000cacSChristoph Hellwig 
569*8f000cacSChristoph Hellwig 	rsp->req.execute(&rsp->req);
570*8f000cacSChristoph Hellwig }
571*8f000cacSChristoph Hellwig 
572*8f000cacSChristoph Hellwig static void nvmet_rdma_use_inline_sg(struct nvmet_rdma_rsp *rsp, u32 len,
573*8f000cacSChristoph Hellwig 		u64 off)
574*8f000cacSChristoph Hellwig {
575*8f000cacSChristoph Hellwig 	sg_init_table(&rsp->cmd->inline_sg, 1);
576*8f000cacSChristoph Hellwig 	sg_set_page(&rsp->cmd->inline_sg, rsp->cmd->inline_page, len, off);
577*8f000cacSChristoph Hellwig 	rsp->req.sg = &rsp->cmd->inline_sg;
578*8f000cacSChristoph Hellwig 	rsp->req.sg_cnt = 1;
579*8f000cacSChristoph Hellwig }
580*8f000cacSChristoph Hellwig 
581*8f000cacSChristoph Hellwig static u16 nvmet_rdma_map_sgl_inline(struct nvmet_rdma_rsp *rsp)
582*8f000cacSChristoph Hellwig {
583*8f000cacSChristoph Hellwig 	struct nvme_sgl_desc *sgl = &rsp->req.cmd->common.dptr.sgl;
584*8f000cacSChristoph Hellwig 	u64 off = le64_to_cpu(sgl->addr);
585*8f000cacSChristoph Hellwig 	u32 len = le32_to_cpu(sgl->length);
586*8f000cacSChristoph Hellwig 
587*8f000cacSChristoph Hellwig 	if (!nvme_is_write(rsp->req.cmd))
588*8f000cacSChristoph Hellwig 		return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
589*8f000cacSChristoph Hellwig 
590*8f000cacSChristoph Hellwig 	if (off + len > NVMET_RDMA_INLINE_DATA_SIZE) {
591*8f000cacSChristoph Hellwig 		pr_err("invalid inline data offset!\n");
592*8f000cacSChristoph Hellwig 		return NVME_SC_SGL_INVALID_OFFSET | NVME_SC_DNR;
593*8f000cacSChristoph Hellwig 	}
594*8f000cacSChristoph Hellwig 
595*8f000cacSChristoph Hellwig 	/* no data command? */
596*8f000cacSChristoph Hellwig 	if (!len)
597*8f000cacSChristoph Hellwig 		return 0;
598*8f000cacSChristoph Hellwig 
599*8f000cacSChristoph Hellwig 	nvmet_rdma_use_inline_sg(rsp, len, off);
600*8f000cacSChristoph Hellwig 	rsp->flags |= NVMET_RDMA_REQ_INLINE_DATA;
601*8f000cacSChristoph Hellwig 	return 0;
602*8f000cacSChristoph Hellwig }
603*8f000cacSChristoph Hellwig 
604*8f000cacSChristoph Hellwig static u16 nvmet_rdma_map_sgl_keyed(struct nvmet_rdma_rsp *rsp,
605*8f000cacSChristoph Hellwig 		struct nvme_keyed_sgl_desc *sgl, bool invalidate)
606*8f000cacSChristoph Hellwig {
607*8f000cacSChristoph Hellwig 	struct rdma_cm_id *cm_id = rsp->queue->cm_id;
608*8f000cacSChristoph Hellwig 	u64 addr = le64_to_cpu(sgl->addr);
609*8f000cacSChristoph Hellwig 	u32 len = get_unaligned_le24(sgl->length);
610*8f000cacSChristoph Hellwig 	u32 key = get_unaligned_le32(sgl->key);
611*8f000cacSChristoph Hellwig 	int ret;
612*8f000cacSChristoph Hellwig 	u16 status;
613*8f000cacSChristoph Hellwig 
614*8f000cacSChristoph Hellwig 	/* no data command? */
615*8f000cacSChristoph Hellwig 	if (!len)
616*8f000cacSChristoph Hellwig 		return 0;
617*8f000cacSChristoph Hellwig 
618*8f000cacSChristoph Hellwig 	/* use the already allocated data buffer if possible */
619*8f000cacSChristoph Hellwig 	if (len <= NVMET_RDMA_INLINE_DATA_SIZE && rsp->queue->host_qid) {
620*8f000cacSChristoph Hellwig 		nvmet_rdma_use_inline_sg(rsp, len, 0);
621*8f000cacSChristoph Hellwig 	} else {
622*8f000cacSChristoph Hellwig 		status = nvmet_rdma_alloc_sgl(&rsp->req.sg, &rsp->req.sg_cnt,
623*8f000cacSChristoph Hellwig 				len);
624*8f000cacSChristoph Hellwig 		if (status)
625*8f000cacSChristoph Hellwig 			return status;
626*8f000cacSChristoph Hellwig 	}
627*8f000cacSChristoph Hellwig 
628*8f000cacSChristoph Hellwig 	ret = rdma_rw_ctx_init(&rsp->rw, cm_id->qp, cm_id->port_num,
629*8f000cacSChristoph Hellwig 			rsp->req.sg, rsp->req.sg_cnt, 0, addr, key,
630*8f000cacSChristoph Hellwig 			nvmet_data_dir(&rsp->req));
631*8f000cacSChristoph Hellwig 	if (ret < 0)
632*8f000cacSChristoph Hellwig 		return NVME_SC_INTERNAL;
633*8f000cacSChristoph Hellwig 	rsp->n_rdma += ret;
634*8f000cacSChristoph Hellwig 
635*8f000cacSChristoph Hellwig 	if (invalidate) {
636*8f000cacSChristoph Hellwig 		rsp->invalidate_rkey = key;
637*8f000cacSChristoph Hellwig 		rsp->flags |= NVMET_RDMA_REQ_INVALIDATE_RKEY;
638*8f000cacSChristoph Hellwig 	}
639*8f000cacSChristoph Hellwig 
640*8f000cacSChristoph Hellwig 	return 0;
641*8f000cacSChristoph Hellwig }
642*8f000cacSChristoph Hellwig 
643*8f000cacSChristoph Hellwig static u16 nvmet_rdma_map_sgl(struct nvmet_rdma_rsp *rsp)
644*8f000cacSChristoph Hellwig {
645*8f000cacSChristoph Hellwig 	struct nvme_keyed_sgl_desc *sgl = &rsp->req.cmd->common.dptr.ksgl;
646*8f000cacSChristoph Hellwig 
647*8f000cacSChristoph Hellwig 	switch (sgl->type >> 4) {
648*8f000cacSChristoph Hellwig 	case NVME_SGL_FMT_DATA_DESC:
649*8f000cacSChristoph Hellwig 		switch (sgl->type & 0xf) {
650*8f000cacSChristoph Hellwig 		case NVME_SGL_FMT_OFFSET:
651*8f000cacSChristoph Hellwig 			return nvmet_rdma_map_sgl_inline(rsp);
652*8f000cacSChristoph Hellwig 		default:
653*8f000cacSChristoph Hellwig 			pr_err("invalid SGL subtype: %#x\n", sgl->type);
654*8f000cacSChristoph Hellwig 			return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
655*8f000cacSChristoph Hellwig 		}
656*8f000cacSChristoph Hellwig 	case NVME_KEY_SGL_FMT_DATA_DESC:
657*8f000cacSChristoph Hellwig 		switch (sgl->type & 0xf) {
658*8f000cacSChristoph Hellwig 		case NVME_SGL_FMT_ADDRESS | NVME_SGL_FMT_INVALIDATE:
659*8f000cacSChristoph Hellwig 			return nvmet_rdma_map_sgl_keyed(rsp, sgl, true);
660*8f000cacSChristoph Hellwig 		case NVME_SGL_FMT_ADDRESS:
661*8f000cacSChristoph Hellwig 			return nvmet_rdma_map_sgl_keyed(rsp, sgl, false);
662*8f000cacSChristoph Hellwig 		default:
663*8f000cacSChristoph Hellwig 			pr_err("invalid SGL subtype: %#x\n", sgl->type);
664*8f000cacSChristoph Hellwig 			return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
665*8f000cacSChristoph Hellwig 		}
666*8f000cacSChristoph Hellwig 	default:
667*8f000cacSChristoph Hellwig 		pr_err("invalid SGL type: %#x\n", sgl->type);
668*8f000cacSChristoph Hellwig 		return NVME_SC_SGL_INVALID_TYPE | NVME_SC_DNR;
669*8f000cacSChristoph Hellwig 	}
670*8f000cacSChristoph Hellwig }
671*8f000cacSChristoph Hellwig 
672*8f000cacSChristoph Hellwig static bool nvmet_rdma_execute_command(struct nvmet_rdma_rsp *rsp)
673*8f000cacSChristoph Hellwig {
674*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue = rsp->queue;
675*8f000cacSChristoph Hellwig 
676*8f000cacSChristoph Hellwig 	if (unlikely(atomic_sub_return(1 + rsp->n_rdma,
677*8f000cacSChristoph Hellwig 			&queue->sq_wr_avail) < 0)) {
678*8f000cacSChristoph Hellwig 		pr_debug("IB send queue full (needed %d): queue %u cntlid %u\n",
679*8f000cacSChristoph Hellwig 				1 + rsp->n_rdma, queue->idx,
680*8f000cacSChristoph Hellwig 				queue->nvme_sq.ctrl->cntlid);
681*8f000cacSChristoph Hellwig 		atomic_add(1 + rsp->n_rdma, &queue->sq_wr_avail);
682*8f000cacSChristoph Hellwig 		return false;
683*8f000cacSChristoph Hellwig 	}
684*8f000cacSChristoph Hellwig 
685*8f000cacSChristoph Hellwig 	if (nvmet_rdma_need_data_in(rsp)) {
686*8f000cacSChristoph Hellwig 		if (rdma_rw_ctx_post(&rsp->rw, queue->cm_id->qp,
687*8f000cacSChristoph Hellwig 				queue->cm_id->port_num, &rsp->read_cqe, NULL))
688*8f000cacSChristoph Hellwig 			nvmet_req_complete(&rsp->req, NVME_SC_DATA_XFER_ERROR);
689*8f000cacSChristoph Hellwig 	} else {
690*8f000cacSChristoph Hellwig 		rsp->req.execute(&rsp->req);
691*8f000cacSChristoph Hellwig 	}
692*8f000cacSChristoph Hellwig 
693*8f000cacSChristoph Hellwig 	return true;
694*8f000cacSChristoph Hellwig }
695*8f000cacSChristoph Hellwig 
696*8f000cacSChristoph Hellwig static void nvmet_rdma_handle_command(struct nvmet_rdma_queue *queue,
697*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *cmd)
698*8f000cacSChristoph Hellwig {
699*8f000cacSChristoph Hellwig 	u16 status;
700*8f000cacSChristoph Hellwig 
701*8f000cacSChristoph Hellwig 	cmd->queue = queue;
702*8f000cacSChristoph Hellwig 	cmd->n_rdma = 0;
703*8f000cacSChristoph Hellwig 	cmd->req.port = queue->port;
704*8f000cacSChristoph Hellwig 
705*8f000cacSChristoph Hellwig 	if (!nvmet_req_init(&cmd->req, &queue->nvme_cq,
706*8f000cacSChristoph Hellwig 			&queue->nvme_sq, &nvmet_rdma_ops))
707*8f000cacSChristoph Hellwig 		return;
708*8f000cacSChristoph Hellwig 
709*8f000cacSChristoph Hellwig 	status = nvmet_rdma_map_sgl(cmd);
710*8f000cacSChristoph Hellwig 	if (status)
711*8f000cacSChristoph Hellwig 		goto out_err;
712*8f000cacSChristoph Hellwig 
713*8f000cacSChristoph Hellwig 	if (unlikely(!nvmet_rdma_execute_command(cmd))) {
714*8f000cacSChristoph Hellwig 		spin_lock(&queue->rsp_wr_wait_lock);
715*8f000cacSChristoph Hellwig 		list_add_tail(&cmd->wait_list, &queue->rsp_wr_wait_list);
716*8f000cacSChristoph Hellwig 		spin_unlock(&queue->rsp_wr_wait_lock);
717*8f000cacSChristoph Hellwig 	}
718*8f000cacSChristoph Hellwig 
719*8f000cacSChristoph Hellwig 	return;
720*8f000cacSChristoph Hellwig 
721*8f000cacSChristoph Hellwig out_err:
722*8f000cacSChristoph Hellwig 	nvmet_req_complete(&cmd->req, status);
723*8f000cacSChristoph Hellwig }
724*8f000cacSChristoph Hellwig 
725*8f000cacSChristoph Hellwig static void nvmet_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc)
726*8f000cacSChristoph Hellwig {
727*8f000cacSChristoph Hellwig 	struct nvmet_rdma_cmd *cmd =
728*8f000cacSChristoph Hellwig 		container_of(wc->wr_cqe, struct nvmet_rdma_cmd, cqe);
729*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue = cq->cq_context;
730*8f000cacSChristoph Hellwig 	struct nvmet_rdma_rsp *rsp;
731*8f000cacSChristoph Hellwig 
732*8f000cacSChristoph Hellwig 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
733*8f000cacSChristoph Hellwig 		if (wc->status != IB_WC_WR_FLUSH_ERR) {
734*8f000cacSChristoph Hellwig 			pr_err("RECV for CQE 0x%p failed with status %s (%d)\n",
735*8f000cacSChristoph Hellwig 				wc->wr_cqe, ib_wc_status_msg(wc->status),
736*8f000cacSChristoph Hellwig 				wc->status);
737*8f000cacSChristoph Hellwig 			nvmet_rdma_error_comp(queue);
738*8f000cacSChristoph Hellwig 		}
739*8f000cacSChristoph Hellwig 		return;
740*8f000cacSChristoph Hellwig 	}
741*8f000cacSChristoph Hellwig 
742*8f000cacSChristoph Hellwig 	if (unlikely(wc->byte_len < sizeof(struct nvme_command))) {
743*8f000cacSChristoph Hellwig 		pr_err("Ctrl Fatal Error: capsule size less than 64 bytes\n");
744*8f000cacSChristoph Hellwig 		nvmet_rdma_error_comp(queue);
745*8f000cacSChristoph Hellwig 		return;
746*8f000cacSChristoph Hellwig 	}
747*8f000cacSChristoph Hellwig 
748*8f000cacSChristoph Hellwig 	cmd->queue = queue;
749*8f000cacSChristoph Hellwig 	rsp = nvmet_rdma_get_rsp(queue);
750*8f000cacSChristoph Hellwig 	rsp->cmd = cmd;
751*8f000cacSChristoph Hellwig 	rsp->flags = 0;
752*8f000cacSChristoph Hellwig 	rsp->req.cmd = cmd->nvme_cmd;
753*8f000cacSChristoph Hellwig 
754*8f000cacSChristoph Hellwig 	if (unlikely(queue->state != NVMET_RDMA_Q_LIVE)) {
755*8f000cacSChristoph Hellwig 		unsigned long flags;
756*8f000cacSChristoph Hellwig 
757*8f000cacSChristoph Hellwig 		spin_lock_irqsave(&queue->state_lock, flags);
758*8f000cacSChristoph Hellwig 		if (queue->state == NVMET_RDMA_Q_CONNECTING)
759*8f000cacSChristoph Hellwig 			list_add_tail(&rsp->wait_list, &queue->rsp_wait_list);
760*8f000cacSChristoph Hellwig 		else
761*8f000cacSChristoph Hellwig 			nvmet_rdma_put_rsp(rsp);
762*8f000cacSChristoph Hellwig 		spin_unlock_irqrestore(&queue->state_lock, flags);
763*8f000cacSChristoph Hellwig 		return;
764*8f000cacSChristoph Hellwig 	}
765*8f000cacSChristoph Hellwig 
766*8f000cacSChristoph Hellwig 	nvmet_rdma_handle_command(queue, rsp);
767*8f000cacSChristoph Hellwig }
768*8f000cacSChristoph Hellwig 
769*8f000cacSChristoph Hellwig static void nvmet_rdma_destroy_srq(struct nvmet_rdma_device *ndev)
770*8f000cacSChristoph Hellwig {
771*8f000cacSChristoph Hellwig 	if (!ndev->srq)
772*8f000cacSChristoph Hellwig 		return;
773*8f000cacSChristoph Hellwig 
774*8f000cacSChristoph Hellwig 	nvmet_rdma_free_cmds(ndev, ndev->srq_cmds, ndev->srq_size, false);
775*8f000cacSChristoph Hellwig 	ib_destroy_srq(ndev->srq);
776*8f000cacSChristoph Hellwig }
777*8f000cacSChristoph Hellwig 
778*8f000cacSChristoph Hellwig static int nvmet_rdma_init_srq(struct nvmet_rdma_device *ndev)
779*8f000cacSChristoph Hellwig {
780*8f000cacSChristoph Hellwig 	struct ib_srq_init_attr srq_attr = { NULL, };
781*8f000cacSChristoph Hellwig 	struct ib_srq *srq;
782*8f000cacSChristoph Hellwig 	size_t srq_size;
783*8f000cacSChristoph Hellwig 	int ret, i;
784*8f000cacSChristoph Hellwig 
785*8f000cacSChristoph Hellwig 	srq_size = 4095;	/* XXX: tune */
786*8f000cacSChristoph Hellwig 
787*8f000cacSChristoph Hellwig 	srq_attr.attr.max_wr = srq_size;
788*8f000cacSChristoph Hellwig 	srq_attr.attr.max_sge = 2;
789*8f000cacSChristoph Hellwig 	srq_attr.attr.srq_limit = 0;
790*8f000cacSChristoph Hellwig 	srq_attr.srq_type = IB_SRQT_BASIC;
791*8f000cacSChristoph Hellwig 	srq = ib_create_srq(ndev->pd, &srq_attr);
792*8f000cacSChristoph Hellwig 	if (IS_ERR(srq)) {
793*8f000cacSChristoph Hellwig 		/*
794*8f000cacSChristoph Hellwig 		 * If SRQs aren't supported we just go ahead and use normal
795*8f000cacSChristoph Hellwig 		 * non-shared receive queues.
796*8f000cacSChristoph Hellwig 		 */
797*8f000cacSChristoph Hellwig 		pr_info("SRQ requested but not supported.\n");
798*8f000cacSChristoph Hellwig 		return 0;
799*8f000cacSChristoph Hellwig 	}
800*8f000cacSChristoph Hellwig 
801*8f000cacSChristoph Hellwig 	ndev->srq_cmds = nvmet_rdma_alloc_cmds(ndev, srq_size, false);
802*8f000cacSChristoph Hellwig 	if (IS_ERR(ndev->srq_cmds)) {
803*8f000cacSChristoph Hellwig 		ret = PTR_ERR(ndev->srq_cmds);
804*8f000cacSChristoph Hellwig 		goto out_destroy_srq;
805*8f000cacSChristoph Hellwig 	}
806*8f000cacSChristoph Hellwig 
807*8f000cacSChristoph Hellwig 	ndev->srq = srq;
808*8f000cacSChristoph Hellwig 	ndev->srq_size = srq_size;
809*8f000cacSChristoph Hellwig 
810*8f000cacSChristoph Hellwig 	for (i = 0; i < srq_size; i++)
811*8f000cacSChristoph Hellwig 		nvmet_rdma_post_recv(ndev, &ndev->srq_cmds[i]);
812*8f000cacSChristoph Hellwig 
813*8f000cacSChristoph Hellwig 	return 0;
814*8f000cacSChristoph Hellwig 
815*8f000cacSChristoph Hellwig out_destroy_srq:
816*8f000cacSChristoph Hellwig 	ib_destroy_srq(srq);
817*8f000cacSChristoph Hellwig 	return ret;
818*8f000cacSChristoph Hellwig }
819*8f000cacSChristoph Hellwig 
820*8f000cacSChristoph Hellwig static void nvmet_rdma_free_dev(struct kref *ref)
821*8f000cacSChristoph Hellwig {
822*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *ndev =
823*8f000cacSChristoph Hellwig 		container_of(ref, struct nvmet_rdma_device, ref);
824*8f000cacSChristoph Hellwig 
825*8f000cacSChristoph Hellwig 	mutex_lock(&device_list_mutex);
826*8f000cacSChristoph Hellwig 	list_del(&ndev->entry);
827*8f000cacSChristoph Hellwig 	mutex_unlock(&device_list_mutex);
828*8f000cacSChristoph Hellwig 
829*8f000cacSChristoph Hellwig 	nvmet_rdma_destroy_srq(ndev);
830*8f000cacSChristoph Hellwig 	ib_dealloc_pd(ndev->pd);
831*8f000cacSChristoph Hellwig 
832*8f000cacSChristoph Hellwig 	kfree(ndev);
833*8f000cacSChristoph Hellwig }
834*8f000cacSChristoph Hellwig 
835*8f000cacSChristoph Hellwig static struct nvmet_rdma_device *
836*8f000cacSChristoph Hellwig nvmet_rdma_find_get_device(struct rdma_cm_id *cm_id)
837*8f000cacSChristoph Hellwig {
838*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *ndev;
839*8f000cacSChristoph Hellwig 	int ret;
840*8f000cacSChristoph Hellwig 
841*8f000cacSChristoph Hellwig 	mutex_lock(&device_list_mutex);
842*8f000cacSChristoph Hellwig 	list_for_each_entry(ndev, &device_list, entry) {
843*8f000cacSChristoph Hellwig 		if (ndev->device->node_guid == cm_id->device->node_guid &&
844*8f000cacSChristoph Hellwig 		    kref_get_unless_zero(&ndev->ref))
845*8f000cacSChristoph Hellwig 			goto out_unlock;
846*8f000cacSChristoph Hellwig 	}
847*8f000cacSChristoph Hellwig 
848*8f000cacSChristoph Hellwig 	ndev = kzalloc(sizeof(*ndev), GFP_KERNEL);
849*8f000cacSChristoph Hellwig 	if (!ndev)
850*8f000cacSChristoph Hellwig 		goto out_err;
851*8f000cacSChristoph Hellwig 
852*8f000cacSChristoph Hellwig 	ndev->device = cm_id->device;
853*8f000cacSChristoph Hellwig 	kref_init(&ndev->ref);
854*8f000cacSChristoph Hellwig 
855*8f000cacSChristoph Hellwig 	ndev->pd = ib_alloc_pd(ndev->device);
856*8f000cacSChristoph Hellwig 	if (IS_ERR(ndev->pd))
857*8f000cacSChristoph Hellwig 		goto out_free_dev;
858*8f000cacSChristoph Hellwig 
859*8f000cacSChristoph Hellwig 	if (nvmet_rdma_use_srq) {
860*8f000cacSChristoph Hellwig 		ret = nvmet_rdma_init_srq(ndev);
861*8f000cacSChristoph Hellwig 		if (ret)
862*8f000cacSChristoph Hellwig 			goto out_free_pd;
863*8f000cacSChristoph Hellwig 	}
864*8f000cacSChristoph Hellwig 
865*8f000cacSChristoph Hellwig 	list_add(&ndev->entry, &device_list);
866*8f000cacSChristoph Hellwig out_unlock:
867*8f000cacSChristoph Hellwig 	mutex_unlock(&device_list_mutex);
868*8f000cacSChristoph Hellwig 	pr_debug("added %s.\n", ndev->device->name);
869*8f000cacSChristoph Hellwig 	return ndev;
870*8f000cacSChristoph Hellwig 
871*8f000cacSChristoph Hellwig out_free_pd:
872*8f000cacSChristoph Hellwig 	ib_dealloc_pd(ndev->pd);
873*8f000cacSChristoph Hellwig out_free_dev:
874*8f000cacSChristoph Hellwig 	kfree(ndev);
875*8f000cacSChristoph Hellwig out_err:
876*8f000cacSChristoph Hellwig 	mutex_unlock(&device_list_mutex);
877*8f000cacSChristoph Hellwig 	return NULL;
878*8f000cacSChristoph Hellwig }
879*8f000cacSChristoph Hellwig 
880*8f000cacSChristoph Hellwig static int nvmet_rdma_create_queue_ib(struct nvmet_rdma_queue *queue)
881*8f000cacSChristoph Hellwig {
882*8f000cacSChristoph Hellwig 	struct ib_qp_init_attr qp_attr;
883*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *ndev = queue->dev;
884*8f000cacSChristoph Hellwig 	int comp_vector, nr_cqe, ret, i;
885*8f000cacSChristoph Hellwig 
886*8f000cacSChristoph Hellwig 	/*
887*8f000cacSChristoph Hellwig 	 * Spread the io queues across completion vectors,
888*8f000cacSChristoph Hellwig 	 * but still keep all admin queues on vector 0.
889*8f000cacSChristoph Hellwig 	 */
890*8f000cacSChristoph Hellwig 	comp_vector = !queue->host_qid ? 0 :
891*8f000cacSChristoph Hellwig 		queue->idx % ndev->device->num_comp_vectors;
892*8f000cacSChristoph Hellwig 
893*8f000cacSChristoph Hellwig 	/*
894*8f000cacSChristoph Hellwig 	 * Reserve CQ slots for RECV + RDMA_READ/RDMA_WRITE + RDMA_SEND.
895*8f000cacSChristoph Hellwig 	 */
896*8f000cacSChristoph Hellwig 	nr_cqe = queue->recv_queue_size + 2 * queue->send_queue_size;
897*8f000cacSChristoph Hellwig 
898*8f000cacSChristoph Hellwig 	queue->cq = ib_alloc_cq(ndev->device, queue,
899*8f000cacSChristoph Hellwig 			nr_cqe + 1, comp_vector,
900*8f000cacSChristoph Hellwig 			IB_POLL_WORKQUEUE);
901*8f000cacSChristoph Hellwig 	if (IS_ERR(queue->cq)) {
902*8f000cacSChristoph Hellwig 		ret = PTR_ERR(queue->cq);
903*8f000cacSChristoph Hellwig 		pr_err("failed to create CQ cqe= %d ret= %d\n",
904*8f000cacSChristoph Hellwig 		       nr_cqe + 1, ret);
905*8f000cacSChristoph Hellwig 		goto out;
906*8f000cacSChristoph Hellwig 	}
907*8f000cacSChristoph Hellwig 
908*8f000cacSChristoph Hellwig 	memset(&qp_attr, 0, sizeof(qp_attr));
909*8f000cacSChristoph Hellwig 	qp_attr.qp_context = queue;
910*8f000cacSChristoph Hellwig 	qp_attr.event_handler = nvmet_rdma_qp_event;
911*8f000cacSChristoph Hellwig 	qp_attr.send_cq = queue->cq;
912*8f000cacSChristoph Hellwig 	qp_attr.recv_cq = queue->cq;
913*8f000cacSChristoph Hellwig 	qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
914*8f000cacSChristoph Hellwig 	qp_attr.qp_type = IB_QPT_RC;
915*8f000cacSChristoph Hellwig 	/* +1 for drain */
916*8f000cacSChristoph Hellwig 	qp_attr.cap.max_send_wr = queue->send_queue_size + 1;
917*8f000cacSChristoph Hellwig 	qp_attr.cap.max_rdma_ctxs = queue->send_queue_size;
918*8f000cacSChristoph Hellwig 	qp_attr.cap.max_send_sge = max(ndev->device->attrs.max_sge_rd,
919*8f000cacSChristoph Hellwig 					ndev->device->attrs.max_sge);
920*8f000cacSChristoph Hellwig 
921*8f000cacSChristoph Hellwig 	if (ndev->srq) {
922*8f000cacSChristoph Hellwig 		qp_attr.srq = ndev->srq;
923*8f000cacSChristoph Hellwig 	} else {
924*8f000cacSChristoph Hellwig 		/* +1 for drain */
925*8f000cacSChristoph Hellwig 		qp_attr.cap.max_recv_wr = 1 + queue->recv_queue_size;
926*8f000cacSChristoph Hellwig 		qp_attr.cap.max_recv_sge = 2;
927*8f000cacSChristoph Hellwig 	}
928*8f000cacSChristoph Hellwig 
929*8f000cacSChristoph Hellwig 	ret = rdma_create_qp(queue->cm_id, ndev->pd, &qp_attr);
930*8f000cacSChristoph Hellwig 	if (ret) {
931*8f000cacSChristoph Hellwig 		pr_err("failed to create_qp ret= %d\n", ret);
932*8f000cacSChristoph Hellwig 		goto err_destroy_cq;
933*8f000cacSChristoph Hellwig 	}
934*8f000cacSChristoph Hellwig 
935*8f000cacSChristoph Hellwig 	atomic_set(&queue->sq_wr_avail, qp_attr.cap.max_send_wr);
936*8f000cacSChristoph Hellwig 
937*8f000cacSChristoph Hellwig 	pr_debug("%s: max_cqe= %d max_sge= %d sq_size = %d cm_id= %p\n",
938*8f000cacSChristoph Hellwig 		 __func__, queue->cq->cqe, qp_attr.cap.max_send_sge,
939*8f000cacSChristoph Hellwig 		 qp_attr.cap.max_send_wr, queue->cm_id);
940*8f000cacSChristoph Hellwig 
941*8f000cacSChristoph Hellwig 	if (!ndev->srq) {
942*8f000cacSChristoph Hellwig 		for (i = 0; i < queue->recv_queue_size; i++) {
943*8f000cacSChristoph Hellwig 			queue->cmds[i].queue = queue;
944*8f000cacSChristoph Hellwig 			nvmet_rdma_post_recv(ndev, &queue->cmds[i]);
945*8f000cacSChristoph Hellwig 		}
946*8f000cacSChristoph Hellwig 	}
947*8f000cacSChristoph Hellwig 
948*8f000cacSChristoph Hellwig out:
949*8f000cacSChristoph Hellwig 	return ret;
950*8f000cacSChristoph Hellwig 
951*8f000cacSChristoph Hellwig err_destroy_cq:
952*8f000cacSChristoph Hellwig 	ib_free_cq(queue->cq);
953*8f000cacSChristoph Hellwig 	goto out;
954*8f000cacSChristoph Hellwig }
955*8f000cacSChristoph Hellwig 
956*8f000cacSChristoph Hellwig static void nvmet_rdma_destroy_queue_ib(struct nvmet_rdma_queue *queue)
957*8f000cacSChristoph Hellwig {
958*8f000cacSChristoph Hellwig 	rdma_destroy_qp(queue->cm_id);
959*8f000cacSChristoph Hellwig 	ib_free_cq(queue->cq);
960*8f000cacSChristoph Hellwig }
961*8f000cacSChristoph Hellwig 
962*8f000cacSChristoph Hellwig static void nvmet_rdma_free_queue(struct nvmet_rdma_queue *queue)
963*8f000cacSChristoph Hellwig {
964*8f000cacSChristoph Hellwig 	pr_info("freeing queue %d\n", queue->idx);
965*8f000cacSChristoph Hellwig 
966*8f000cacSChristoph Hellwig 	nvmet_sq_destroy(&queue->nvme_sq);
967*8f000cacSChristoph Hellwig 
968*8f000cacSChristoph Hellwig 	nvmet_rdma_destroy_queue_ib(queue);
969*8f000cacSChristoph Hellwig 	if (!queue->dev->srq) {
970*8f000cacSChristoph Hellwig 		nvmet_rdma_free_cmds(queue->dev, queue->cmds,
971*8f000cacSChristoph Hellwig 				queue->recv_queue_size,
972*8f000cacSChristoph Hellwig 				!queue->host_qid);
973*8f000cacSChristoph Hellwig 	}
974*8f000cacSChristoph Hellwig 	nvmet_rdma_free_rsps(queue);
975*8f000cacSChristoph Hellwig 	ida_simple_remove(&nvmet_rdma_queue_ida, queue->idx);
976*8f000cacSChristoph Hellwig 	kfree(queue);
977*8f000cacSChristoph Hellwig }
978*8f000cacSChristoph Hellwig 
979*8f000cacSChristoph Hellwig static void nvmet_rdma_release_queue_work(struct work_struct *w)
980*8f000cacSChristoph Hellwig {
981*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue =
982*8f000cacSChristoph Hellwig 		container_of(w, struct nvmet_rdma_queue, release_work);
983*8f000cacSChristoph Hellwig 	struct rdma_cm_id *cm_id = queue->cm_id;
984*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *dev = queue->dev;
985*8f000cacSChristoph Hellwig 
986*8f000cacSChristoph Hellwig 	nvmet_rdma_free_queue(queue);
987*8f000cacSChristoph Hellwig 	rdma_destroy_id(cm_id);
988*8f000cacSChristoph Hellwig 	kref_put(&dev->ref, nvmet_rdma_free_dev);
989*8f000cacSChristoph Hellwig }
990*8f000cacSChristoph Hellwig 
991*8f000cacSChristoph Hellwig static int
992*8f000cacSChristoph Hellwig nvmet_rdma_parse_cm_connect_req(struct rdma_conn_param *conn,
993*8f000cacSChristoph Hellwig 				struct nvmet_rdma_queue *queue)
994*8f000cacSChristoph Hellwig {
995*8f000cacSChristoph Hellwig 	struct nvme_rdma_cm_req *req;
996*8f000cacSChristoph Hellwig 
997*8f000cacSChristoph Hellwig 	req = (struct nvme_rdma_cm_req *)conn->private_data;
998*8f000cacSChristoph Hellwig 	if (!req || conn->private_data_len == 0)
999*8f000cacSChristoph Hellwig 		return NVME_RDMA_CM_INVALID_LEN;
1000*8f000cacSChristoph Hellwig 
1001*8f000cacSChristoph Hellwig 	if (le16_to_cpu(req->recfmt) != NVME_RDMA_CM_FMT_1_0)
1002*8f000cacSChristoph Hellwig 		return NVME_RDMA_CM_INVALID_RECFMT;
1003*8f000cacSChristoph Hellwig 
1004*8f000cacSChristoph Hellwig 	queue->host_qid = le16_to_cpu(req->qid);
1005*8f000cacSChristoph Hellwig 
1006*8f000cacSChristoph Hellwig 	/*
1007*8f000cacSChristoph Hellwig 	 * req->hsqsize corresponds to our recv queue size
1008*8f000cacSChristoph Hellwig 	 * req->hrqsize corresponds to our send queue size
1009*8f000cacSChristoph Hellwig 	 */
1010*8f000cacSChristoph Hellwig 	queue->recv_queue_size = le16_to_cpu(req->hsqsize);
1011*8f000cacSChristoph Hellwig 	queue->send_queue_size = le16_to_cpu(req->hrqsize);
1012*8f000cacSChristoph Hellwig 
1013*8f000cacSChristoph Hellwig 	if (!queue->host_qid && queue->recv_queue_size > NVMF_AQ_DEPTH)
1014*8f000cacSChristoph Hellwig 		return NVME_RDMA_CM_INVALID_HSQSIZE;
1015*8f000cacSChristoph Hellwig 
1016*8f000cacSChristoph Hellwig 	/* XXX: Should we enforce some kind of max for IO queues? */
1017*8f000cacSChristoph Hellwig 
1018*8f000cacSChristoph Hellwig 	return 0;
1019*8f000cacSChristoph Hellwig }
1020*8f000cacSChristoph Hellwig 
1021*8f000cacSChristoph Hellwig static int nvmet_rdma_cm_reject(struct rdma_cm_id *cm_id,
1022*8f000cacSChristoph Hellwig 				enum nvme_rdma_cm_status status)
1023*8f000cacSChristoph Hellwig {
1024*8f000cacSChristoph Hellwig 	struct nvme_rdma_cm_rej rej;
1025*8f000cacSChristoph Hellwig 
1026*8f000cacSChristoph Hellwig 	rej.recfmt = cpu_to_le16(NVME_RDMA_CM_FMT_1_0);
1027*8f000cacSChristoph Hellwig 	rej.sts = cpu_to_le16(status);
1028*8f000cacSChristoph Hellwig 
1029*8f000cacSChristoph Hellwig 	return rdma_reject(cm_id, (void *)&rej, sizeof(rej));
1030*8f000cacSChristoph Hellwig }
1031*8f000cacSChristoph Hellwig 
1032*8f000cacSChristoph Hellwig static struct nvmet_rdma_queue *
1033*8f000cacSChristoph Hellwig nvmet_rdma_alloc_queue(struct nvmet_rdma_device *ndev,
1034*8f000cacSChristoph Hellwig 		struct rdma_cm_id *cm_id,
1035*8f000cacSChristoph Hellwig 		struct rdma_cm_event *event)
1036*8f000cacSChristoph Hellwig {
1037*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue;
1038*8f000cacSChristoph Hellwig 	int ret;
1039*8f000cacSChristoph Hellwig 
1040*8f000cacSChristoph Hellwig 	queue = kzalloc(sizeof(*queue), GFP_KERNEL);
1041*8f000cacSChristoph Hellwig 	if (!queue) {
1042*8f000cacSChristoph Hellwig 		ret = NVME_RDMA_CM_NO_RSC;
1043*8f000cacSChristoph Hellwig 		goto out_reject;
1044*8f000cacSChristoph Hellwig 	}
1045*8f000cacSChristoph Hellwig 
1046*8f000cacSChristoph Hellwig 	ret = nvmet_sq_init(&queue->nvme_sq);
1047*8f000cacSChristoph Hellwig 	if (ret)
1048*8f000cacSChristoph Hellwig 		goto out_free_queue;
1049*8f000cacSChristoph Hellwig 
1050*8f000cacSChristoph Hellwig 	ret = nvmet_rdma_parse_cm_connect_req(&event->param.conn, queue);
1051*8f000cacSChristoph Hellwig 	if (ret)
1052*8f000cacSChristoph Hellwig 		goto out_destroy_sq;
1053*8f000cacSChristoph Hellwig 
1054*8f000cacSChristoph Hellwig 	/*
1055*8f000cacSChristoph Hellwig 	 * Schedules the actual release because calling rdma_destroy_id from
1056*8f000cacSChristoph Hellwig 	 * inside a CM callback would trigger a deadlock. (great API design..)
1057*8f000cacSChristoph Hellwig 	 */
1058*8f000cacSChristoph Hellwig 	INIT_WORK(&queue->release_work, nvmet_rdma_release_queue_work);
1059*8f000cacSChristoph Hellwig 	queue->dev = ndev;
1060*8f000cacSChristoph Hellwig 	queue->cm_id = cm_id;
1061*8f000cacSChristoph Hellwig 
1062*8f000cacSChristoph Hellwig 	spin_lock_init(&queue->state_lock);
1063*8f000cacSChristoph Hellwig 	queue->state = NVMET_RDMA_Q_CONNECTING;
1064*8f000cacSChristoph Hellwig 	INIT_LIST_HEAD(&queue->rsp_wait_list);
1065*8f000cacSChristoph Hellwig 	INIT_LIST_HEAD(&queue->rsp_wr_wait_list);
1066*8f000cacSChristoph Hellwig 	spin_lock_init(&queue->rsp_wr_wait_lock);
1067*8f000cacSChristoph Hellwig 	INIT_LIST_HEAD(&queue->free_rsps);
1068*8f000cacSChristoph Hellwig 	spin_lock_init(&queue->rsps_lock);
1069*8f000cacSChristoph Hellwig 
1070*8f000cacSChristoph Hellwig 	queue->idx = ida_simple_get(&nvmet_rdma_queue_ida, 0, 0, GFP_KERNEL);
1071*8f000cacSChristoph Hellwig 	if (queue->idx < 0) {
1072*8f000cacSChristoph Hellwig 		ret = NVME_RDMA_CM_NO_RSC;
1073*8f000cacSChristoph Hellwig 		goto out_free_queue;
1074*8f000cacSChristoph Hellwig 	}
1075*8f000cacSChristoph Hellwig 
1076*8f000cacSChristoph Hellwig 	ret = nvmet_rdma_alloc_rsps(queue);
1077*8f000cacSChristoph Hellwig 	if (ret) {
1078*8f000cacSChristoph Hellwig 		ret = NVME_RDMA_CM_NO_RSC;
1079*8f000cacSChristoph Hellwig 		goto out_ida_remove;
1080*8f000cacSChristoph Hellwig 	}
1081*8f000cacSChristoph Hellwig 
1082*8f000cacSChristoph Hellwig 	if (!ndev->srq) {
1083*8f000cacSChristoph Hellwig 		queue->cmds = nvmet_rdma_alloc_cmds(ndev,
1084*8f000cacSChristoph Hellwig 				queue->recv_queue_size,
1085*8f000cacSChristoph Hellwig 				!queue->host_qid);
1086*8f000cacSChristoph Hellwig 		if (IS_ERR(queue->cmds)) {
1087*8f000cacSChristoph Hellwig 			ret = NVME_RDMA_CM_NO_RSC;
1088*8f000cacSChristoph Hellwig 			goto out_free_responses;
1089*8f000cacSChristoph Hellwig 		}
1090*8f000cacSChristoph Hellwig 	}
1091*8f000cacSChristoph Hellwig 
1092*8f000cacSChristoph Hellwig 	ret = nvmet_rdma_create_queue_ib(queue);
1093*8f000cacSChristoph Hellwig 	if (ret) {
1094*8f000cacSChristoph Hellwig 		pr_err("%s: creating RDMA queue failed (%d).\n",
1095*8f000cacSChristoph Hellwig 			__func__, ret);
1096*8f000cacSChristoph Hellwig 		ret = NVME_RDMA_CM_NO_RSC;
1097*8f000cacSChristoph Hellwig 		goto out_free_cmds;
1098*8f000cacSChristoph Hellwig 	}
1099*8f000cacSChristoph Hellwig 
1100*8f000cacSChristoph Hellwig 	return queue;
1101*8f000cacSChristoph Hellwig 
1102*8f000cacSChristoph Hellwig out_free_cmds:
1103*8f000cacSChristoph Hellwig 	if (!ndev->srq) {
1104*8f000cacSChristoph Hellwig 		nvmet_rdma_free_cmds(queue->dev, queue->cmds,
1105*8f000cacSChristoph Hellwig 				queue->recv_queue_size,
1106*8f000cacSChristoph Hellwig 				!queue->host_qid);
1107*8f000cacSChristoph Hellwig 	}
1108*8f000cacSChristoph Hellwig out_free_responses:
1109*8f000cacSChristoph Hellwig 	nvmet_rdma_free_rsps(queue);
1110*8f000cacSChristoph Hellwig out_ida_remove:
1111*8f000cacSChristoph Hellwig 	ida_simple_remove(&nvmet_rdma_queue_ida, queue->idx);
1112*8f000cacSChristoph Hellwig out_destroy_sq:
1113*8f000cacSChristoph Hellwig 	nvmet_sq_destroy(&queue->nvme_sq);
1114*8f000cacSChristoph Hellwig out_free_queue:
1115*8f000cacSChristoph Hellwig 	kfree(queue);
1116*8f000cacSChristoph Hellwig out_reject:
1117*8f000cacSChristoph Hellwig 	nvmet_rdma_cm_reject(cm_id, ret);
1118*8f000cacSChristoph Hellwig 	return NULL;
1119*8f000cacSChristoph Hellwig }
1120*8f000cacSChristoph Hellwig 
1121*8f000cacSChristoph Hellwig static void nvmet_rdma_qp_event(struct ib_event *event, void *priv)
1122*8f000cacSChristoph Hellwig {
1123*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue = priv;
1124*8f000cacSChristoph Hellwig 
1125*8f000cacSChristoph Hellwig 	switch (event->event) {
1126*8f000cacSChristoph Hellwig 	case IB_EVENT_COMM_EST:
1127*8f000cacSChristoph Hellwig 		rdma_notify(queue->cm_id, event->event);
1128*8f000cacSChristoph Hellwig 		break;
1129*8f000cacSChristoph Hellwig 	default:
1130*8f000cacSChristoph Hellwig 		pr_err("received unrecognized IB QP event %d\n", event->event);
1131*8f000cacSChristoph Hellwig 		break;
1132*8f000cacSChristoph Hellwig 	}
1133*8f000cacSChristoph Hellwig }
1134*8f000cacSChristoph Hellwig 
1135*8f000cacSChristoph Hellwig static int nvmet_rdma_cm_accept(struct rdma_cm_id *cm_id,
1136*8f000cacSChristoph Hellwig 		struct nvmet_rdma_queue *queue,
1137*8f000cacSChristoph Hellwig 		struct rdma_conn_param *p)
1138*8f000cacSChristoph Hellwig {
1139*8f000cacSChristoph Hellwig 	struct rdma_conn_param  param = { };
1140*8f000cacSChristoph Hellwig 	struct nvme_rdma_cm_rep priv = { };
1141*8f000cacSChristoph Hellwig 	int ret = -ENOMEM;
1142*8f000cacSChristoph Hellwig 
1143*8f000cacSChristoph Hellwig 	param.rnr_retry_count = 7;
1144*8f000cacSChristoph Hellwig 	param.flow_control = 1;
1145*8f000cacSChristoph Hellwig 	param.initiator_depth = min_t(u8, p->initiator_depth,
1146*8f000cacSChristoph Hellwig 		queue->dev->device->attrs.max_qp_init_rd_atom);
1147*8f000cacSChristoph Hellwig 	param.private_data = &priv;
1148*8f000cacSChristoph Hellwig 	param.private_data_len = sizeof(priv);
1149*8f000cacSChristoph Hellwig 	priv.recfmt = cpu_to_le16(NVME_RDMA_CM_FMT_1_0);
1150*8f000cacSChristoph Hellwig 	priv.crqsize = cpu_to_le16(queue->recv_queue_size);
1151*8f000cacSChristoph Hellwig 
1152*8f000cacSChristoph Hellwig 	ret = rdma_accept(cm_id, &param);
1153*8f000cacSChristoph Hellwig 	if (ret)
1154*8f000cacSChristoph Hellwig 		pr_err("rdma_accept failed (error code = %d)\n", ret);
1155*8f000cacSChristoph Hellwig 
1156*8f000cacSChristoph Hellwig 	return ret;
1157*8f000cacSChristoph Hellwig }
1158*8f000cacSChristoph Hellwig 
1159*8f000cacSChristoph Hellwig static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
1160*8f000cacSChristoph Hellwig 		struct rdma_cm_event *event)
1161*8f000cacSChristoph Hellwig {
1162*8f000cacSChristoph Hellwig 	struct nvmet_rdma_device *ndev;
1163*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue;
1164*8f000cacSChristoph Hellwig 	int ret = -EINVAL;
1165*8f000cacSChristoph Hellwig 
1166*8f000cacSChristoph Hellwig 	ndev = nvmet_rdma_find_get_device(cm_id);
1167*8f000cacSChristoph Hellwig 	if (!ndev) {
1168*8f000cacSChristoph Hellwig 		pr_err("no client data!\n");
1169*8f000cacSChristoph Hellwig 		nvmet_rdma_cm_reject(cm_id, NVME_RDMA_CM_NO_RSC);
1170*8f000cacSChristoph Hellwig 		return -ECONNREFUSED;
1171*8f000cacSChristoph Hellwig 	}
1172*8f000cacSChristoph Hellwig 
1173*8f000cacSChristoph Hellwig 	queue = nvmet_rdma_alloc_queue(ndev, cm_id, event);
1174*8f000cacSChristoph Hellwig 	if (!queue) {
1175*8f000cacSChristoph Hellwig 		ret = -ENOMEM;
1176*8f000cacSChristoph Hellwig 		goto put_device;
1177*8f000cacSChristoph Hellwig 	}
1178*8f000cacSChristoph Hellwig 	queue->port = cm_id->context;
1179*8f000cacSChristoph Hellwig 
1180*8f000cacSChristoph Hellwig 	ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
1181*8f000cacSChristoph Hellwig 	if (ret)
1182*8f000cacSChristoph Hellwig 		goto release_queue;
1183*8f000cacSChristoph Hellwig 
1184*8f000cacSChristoph Hellwig 	mutex_lock(&nvmet_rdma_queue_mutex);
1185*8f000cacSChristoph Hellwig 	list_add_tail(&queue->queue_list, &nvmet_rdma_queue_list);
1186*8f000cacSChristoph Hellwig 	mutex_unlock(&nvmet_rdma_queue_mutex);
1187*8f000cacSChristoph Hellwig 
1188*8f000cacSChristoph Hellwig 	return 0;
1189*8f000cacSChristoph Hellwig 
1190*8f000cacSChristoph Hellwig release_queue:
1191*8f000cacSChristoph Hellwig 	nvmet_rdma_free_queue(queue);
1192*8f000cacSChristoph Hellwig put_device:
1193*8f000cacSChristoph Hellwig 	kref_put(&ndev->ref, nvmet_rdma_free_dev);
1194*8f000cacSChristoph Hellwig 
1195*8f000cacSChristoph Hellwig 	return ret;
1196*8f000cacSChristoph Hellwig }
1197*8f000cacSChristoph Hellwig 
1198*8f000cacSChristoph Hellwig static void nvmet_rdma_queue_established(struct nvmet_rdma_queue *queue)
1199*8f000cacSChristoph Hellwig {
1200*8f000cacSChristoph Hellwig 	unsigned long flags;
1201*8f000cacSChristoph Hellwig 
1202*8f000cacSChristoph Hellwig 	spin_lock_irqsave(&queue->state_lock, flags);
1203*8f000cacSChristoph Hellwig 	if (queue->state != NVMET_RDMA_Q_CONNECTING) {
1204*8f000cacSChristoph Hellwig 		pr_warn("trying to establish a connected queue\n");
1205*8f000cacSChristoph Hellwig 		goto out_unlock;
1206*8f000cacSChristoph Hellwig 	}
1207*8f000cacSChristoph Hellwig 	queue->state = NVMET_RDMA_Q_LIVE;
1208*8f000cacSChristoph Hellwig 
1209*8f000cacSChristoph Hellwig 	while (!list_empty(&queue->rsp_wait_list)) {
1210*8f000cacSChristoph Hellwig 		struct nvmet_rdma_rsp *cmd;
1211*8f000cacSChristoph Hellwig 
1212*8f000cacSChristoph Hellwig 		cmd = list_first_entry(&queue->rsp_wait_list,
1213*8f000cacSChristoph Hellwig 					struct nvmet_rdma_rsp, wait_list);
1214*8f000cacSChristoph Hellwig 		list_del(&cmd->wait_list);
1215*8f000cacSChristoph Hellwig 
1216*8f000cacSChristoph Hellwig 		spin_unlock_irqrestore(&queue->state_lock, flags);
1217*8f000cacSChristoph Hellwig 		nvmet_rdma_handle_command(queue, cmd);
1218*8f000cacSChristoph Hellwig 		spin_lock_irqsave(&queue->state_lock, flags);
1219*8f000cacSChristoph Hellwig 	}
1220*8f000cacSChristoph Hellwig 
1221*8f000cacSChristoph Hellwig out_unlock:
1222*8f000cacSChristoph Hellwig 	spin_unlock_irqrestore(&queue->state_lock, flags);
1223*8f000cacSChristoph Hellwig }
1224*8f000cacSChristoph Hellwig 
1225*8f000cacSChristoph Hellwig static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue)
1226*8f000cacSChristoph Hellwig {
1227*8f000cacSChristoph Hellwig 	bool disconnect = false;
1228*8f000cacSChristoph Hellwig 	unsigned long flags;
1229*8f000cacSChristoph Hellwig 
1230*8f000cacSChristoph Hellwig 	pr_debug("cm_id= %p queue->state= %d\n", queue->cm_id, queue->state);
1231*8f000cacSChristoph Hellwig 
1232*8f000cacSChristoph Hellwig 	spin_lock_irqsave(&queue->state_lock, flags);
1233*8f000cacSChristoph Hellwig 	switch (queue->state) {
1234*8f000cacSChristoph Hellwig 	case NVMET_RDMA_Q_CONNECTING:
1235*8f000cacSChristoph Hellwig 	case NVMET_RDMA_Q_LIVE:
1236*8f000cacSChristoph Hellwig 		disconnect = true;
1237*8f000cacSChristoph Hellwig 		queue->state = NVMET_RDMA_Q_DISCONNECTING;
1238*8f000cacSChristoph Hellwig 		break;
1239*8f000cacSChristoph Hellwig 	case NVMET_RDMA_Q_DISCONNECTING:
1240*8f000cacSChristoph Hellwig 		break;
1241*8f000cacSChristoph Hellwig 	}
1242*8f000cacSChristoph Hellwig 	spin_unlock_irqrestore(&queue->state_lock, flags);
1243*8f000cacSChristoph Hellwig 
1244*8f000cacSChristoph Hellwig 	if (disconnect) {
1245*8f000cacSChristoph Hellwig 		rdma_disconnect(queue->cm_id);
1246*8f000cacSChristoph Hellwig 		ib_drain_qp(queue->cm_id->qp);
1247*8f000cacSChristoph Hellwig 		schedule_work(&queue->release_work);
1248*8f000cacSChristoph Hellwig 	}
1249*8f000cacSChristoph Hellwig }
1250*8f000cacSChristoph Hellwig 
1251*8f000cacSChristoph Hellwig static void nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue)
1252*8f000cacSChristoph Hellwig {
1253*8f000cacSChristoph Hellwig 	bool disconnect = false;
1254*8f000cacSChristoph Hellwig 
1255*8f000cacSChristoph Hellwig 	mutex_lock(&nvmet_rdma_queue_mutex);
1256*8f000cacSChristoph Hellwig 	if (!list_empty(&queue->queue_list)) {
1257*8f000cacSChristoph Hellwig 		list_del_init(&queue->queue_list);
1258*8f000cacSChristoph Hellwig 		disconnect = true;
1259*8f000cacSChristoph Hellwig 	}
1260*8f000cacSChristoph Hellwig 	mutex_unlock(&nvmet_rdma_queue_mutex);
1261*8f000cacSChristoph Hellwig 
1262*8f000cacSChristoph Hellwig 	if (disconnect)
1263*8f000cacSChristoph Hellwig 		__nvmet_rdma_queue_disconnect(queue);
1264*8f000cacSChristoph Hellwig }
1265*8f000cacSChristoph Hellwig 
1266*8f000cacSChristoph Hellwig static void nvmet_rdma_queue_connect_fail(struct rdma_cm_id *cm_id,
1267*8f000cacSChristoph Hellwig 		struct nvmet_rdma_queue *queue)
1268*8f000cacSChristoph Hellwig {
1269*8f000cacSChristoph Hellwig 	WARN_ON_ONCE(queue->state != NVMET_RDMA_Q_CONNECTING);
1270*8f000cacSChristoph Hellwig 
1271*8f000cacSChristoph Hellwig 	pr_err("failed to connect queue\n");
1272*8f000cacSChristoph Hellwig 	schedule_work(&queue->release_work);
1273*8f000cacSChristoph Hellwig }
1274*8f000cacSChristoph Hellwig 
1275*8f000cacSChristoph Hellwig static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id,
1276*8f000cacSChristoph Hellwig 		struct rdma_cm_event *event)
1277*8f000cacSChristoph Hellwig {
1278*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue = NULL;
1279*8f000cacSChristoph Hellwig 	int ret = 0;
1280*8f000cacSChristoph Hellwig 
1281*8f000cacSChristoph Hellwig 	if (cm_id->qp)
1282*8f000cacSChristoph Hellwig 		queue = cm_id->qp->qp_context;
1283*8f000cacSChristoph Hellwig 
1284*8f000cacSChristoph Hellwig 	pr_debug("%s (%d): status %d id %p\n",
1285*8f000cacSChristoph Hellwig 		rdma_event_msg(event->event), event->event,
1286*8f000cacSChristoph Hellwig 		event->status, cm_id);
1287*8f000cacSChristoph Hellwig 
1288*8f000cacSChristoph Hellwig 	switch (event->event) {
1289*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_CONNECT_REQUEST:
1290*8f000cacSChristoph Hellwig 		ret = nvmet_rdma_queue_connect(cm_id, event);
1291*8f000cacSChristoph Hellwig 		break;
1292*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_ESTABLISHED:
1293*8f000cacSChristoph Hellwig 		nvmet_rdma_queue_established(queue);
1294*8f000cacSChristoph Hellwig 		break;
1295*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_ADDR_CHANGE:
1296*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_DISCONNECTED:
1297*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
1298*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_TIMEWAIT_EXIT:
1299*8f000cacSChristoph Hellwig 		/*
1300*8f000cacSChristoph Hellwig 		 * We can get the device removal callback even for a
1301*8f000cacSChristoph Hellwig 		 * CM ID that we aren't actually using.  In that case
1302*8f000cacSChristoph Hellwig 		 * the context pointer is NULL, so we shouldn't try
1303*8f000cacSChristoph Hellwig 		 * to disconnect a non-existing queue.  But we also
1304*8f000cacSChristoph Hellwig 		 * need to return 1 so that the core will destroy
1305*8f000cacSChristoph Hellwig 		 * it's own ID.  What a great API design..
1306*8f000cacSChristoph Hellwig 		 */
1307*8f000cacSChristoph Hellwig 		if (queue)
1308*8f000cacSChristoph Hellwig 			nvmet_rdma_queue_disconnect(queue);
1309*8f000cacSChristoph Hellwig 		else
1310*8f000cacSChristoph Hellwig 			ret = 1;
1311*8f000cacSChristoph Hellwig 		break;
1312*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_REJECTED:
1313*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_UNREACHABLE:
1314*8f000cacSChristoph Hellwig 	case RDMA_CM_EVENT_CONNECT_ERROR:
1315*8f000cacSChristoph Hellwig 		nvmet_rdma_queue_connect_fail(cm_id, queue);
1316*8f000cacSChristoph Hellwig 		break;
1317*8f000cacSChristoph Hellwig 	default:
1318*8f000cacSChristoph Hellwig 		pr_err("received unrecognized RDMA CM event %d\n",
1319*8f000cacSChristoph Hellwig 			event->event);
1320*8f000cacSChristoph Hellwig 		break;
1321*8f000cacSChristoph Hellwig 	}
1322*8f000cacSChristoph Hellwig 
1323*8f000cacSChristoph Hellwig 	return ret;
1324*8f000cacSChristoph Hellwig }
1325*8f000cacSChristoph Hellwig 
1326*8f000cacSChristoph Hellwig static void nvmet_rdma_delete_ctrl(struct nvmet_ctrl *ctrl)
1327*8f000cacSChristoph Hellwig {
1328*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue;
1329*8f000cacSChristoph Hellwig 
1330*8f000cacSChristoph Hellwig restart:
1331*8f000cacSChristoph Hellwig 	mutex_lock(&nvmet_rdma_queue_mutex);
1332*8f000cacSChristoph Hellwig 	list_for_each_entry(queue, &nvmet_rdma_queue_list, queue_list) {
1333*8f000cacSChristoph Hellwig 		if (queue->nvme_sq.ctrl == ctrl) {
1334*8f000cacSChristoph Hellwig 			list_del_init(&queue->queue_list);
1335*8f000cacSChristoph Hellwig 			mutex_unlock(&nvmet_rdma_queue_mutex);
1336*8f000cacSChristoph Hellwig 
1337*8f000cacSChristoph Hellwig 			__nvmet_rdma_queue_disconnect(queue);
1338*8f000cacSChristoph Hellwig 			goto restart;
1339*8f000cacSChristoph Hellwig 		}
1340*8f000cacSChristoph Hellwig 	}
1341*8f000cacSChristoph Hellwig 	mutex_unlock(&nvmet_rdma_queue_mutex);
1342*8f000cacSChristoph Hellwig }
1343*8f000cacSChristoph Hellwig 
1344*8f000cacSChristoph Hellwig static int nvmet_rdma_add_port(struct nvmet_port *port)
1345*8f000cacSChristoph Hellwig {
1346*8f000cacSChristoph Hellwig 	struct rdma_cm_id *cm_id;
1347*8f000cacSChristoph Hellwig 	struct sockaddr_in addr_in;
1348*8f000cacSChristoph Hellwig 	u16 port_in;
1349*8f000cacSChristoph Hellwig 	int ret;
1350*8f000cacSChristoph Hellwig 
1351*8f000cacSChristoph Hellwig 	switch (port->disc_addr.adrfam) {
1352*8f000cacSChristoph Hellwig 	case NVMF_ADDR_FAMILY_IP4:
1353*8f000cacSChristoph Hellwig 		break;
1354*8f000cacSChristoph Hellwig 	default:
1355*8f000cacSChristoph Hellwig 		pr_err("address family %d not supported\n",
1356*8f000cacSChristoph Hellwig 				port->disc_addr.adrfam);
1357*8f000cacSChristoph Hellwig 		return -EINVAL;
1358*8f000cacSChristoph Hellwig 	}
1359*8f000cacSChristoph Hellwig 
1360*8f000cacSChristoph Hellwig 	ret = kstrtou16(port->disc_addr.trsvcid, 0, &port_in);
1361*8f000cacSChristoph Hellwig 	if (ret)
1362*8f000cacSChristoph Hellwig 		return ret;
1363*8f000cacSChristoph Hellwig 
1364*8f000cacSChristoph Hellwig 	addr_in.sin_family = AF_INET;
1365*8f000cacSChristoph Hellwig 	addr_in.sin_addr.s_addr = in_aton(port->disc_addr.traddr);
1366*8f000cacSChristoph Hellwig 	addr_in.sin_port = htons(port_in);
1367*8f000cacSChristoph Hellwig 
1368*8f000cacSChristoph Hellwig 	cm_id = rdma_create_id(&init_net, nvmet_rdma_cm_handler, port,
1369*8f000cacSChristoph Hellwig 			RDMA_PS_TCP, IB_QPT_RC);
1370*8f000cacSChristoph Hellwig 	if (IS_ERR(cm_id)) {
1371*8f000cacSChristoph Hellwig 		pr_err("CM ID creation failed\n");
1372*8f000cacSChristoph Hellwig 		return PTR_ERR(cm_id);
1373*8f000cacSChristoph Hellwig 	}
1374*8f000cacSChristoph Hellwig 
1375*8f000cacSChristoph Hellwig 	ret = rdma_bind_addr(cm_id, (struct sockaddr *)&addr_in);
1376*8f000cacSChristoph Hellwig 	if (ret) {
1377*8f000cacSChristoph Hellwig 		pr_err("binding CM ID to %pISpc failed (%d)\n", &addr_in, ret);
1378*8f000cacSChristoph Hellwig 		goto out_destroy_id;
1379*8f000cacSChristoph Hellwig 	}
1380*8f000cacSChristoph Hellwig 
1381*8f000cacSChristoph Hellwig 	ret = rdma_listen(cm_id, 128);
1382*8f000cacSChristoph Hellwig 	if (ret) {
1383*8f000cacSChristoph Hellwig 		pr_err("listening to %pISpc failed (%d)\n", &addr_in, ret);
1384*8f000cacSChristoph Hellwig 		goto out_destroy_id;
1385*8f000cacSChristoph Hellwig 	}
1386*8f000cacSChristoph Hellwig 
1387*8f000cacSChristoph Hellwig 	pr_info("enabling port %d (%pISpc)\n",
1388*8f000cacSChristoph Hellwig 		le16_to_cpu(port->disc_addr.portid), &addr_in);
1389*8f000cacSChristoph Hellwig 	port->priv = cm_id;
1390*8f000cacSChristoph Hellwig 	return 0;
1391*8f000cacSChristoph Hellwig 
1392*8f000cacSChristoph Hellwig out_destroy_id:
1393*8f000cacSChristoph Hellwig 	rdma_destroy_id(cm_id);
1394*8f000cacSChristoph Hellwig 	return ret;
1395*8f000cacSChristoph Hellwig }
1396*8f000cacSChristoph Hellwig 
1397*8f000cacSChristoph Hellwig static void nvmet_rdma_remove_port(struct nvmet_port *port)
1398*8f000cacSChristoph Hellwig {
1399*8f000cacSChristoph Hellwig 	struct rdma_cm_id *cm_id = port->priv;
1400*8f000cacSChristoph Hellwig 
1401*8f000cacSChristoph Hellwig 	rdma_destroy_id(cm_id);
1402*8f000cacSChristoph Hellwig }
1403*8f000cacSChristoph Hellwig 
1404*8f000cacSChristoph Hellwig static struct nvmet_fabrics_ops nvmet_rdma_ops = {
1405*8f000cacSChristoph Hellwig 	.owner			= THIS_MODULE,
1406*8f000cacSChristoph Hellwig 	.type			= NVMF_TRTYPE_RDMA,
1407*8f000cacSChristoph Hellwig 	.sqe_inline_size	= NVMET_RDMA_INLINE_DATA_SIZE,
1408*8f000cacSChristoph Hellwig 	.msdbd			= 1,
1409*8f000cacSChristoph Hellwig 	.has_keyed_sgls		= 1,
1410*8f000cacSChristoph Hellwig 	.add_port		= nvmet_rdma_add_port,
1411*8f000cacSChristoph Hellwig 	.remove_port		= nvmet_rdma_remove_port,
1412*8f000cacSChristoph Hellwig 	.queue_response		= nvmet_rdma_queue_response,
1413*8f000cacSChristoph Hellwig 	.delete_ctrl		= nvmet_rdma_delete_ctrl,
1414*8f000cacSChristoph Hellwig };
1415*8f000cacSChristoph Hellwig 
1416*8f000cacSChristoph Hellwig static int __init nvmet_rdma_init(void)
1417*8f000cacSChristoph Hellwig {
1418*8f000cacSChristoph Hellwig 	return nvmet_register_transport(&nvmet_rdma_ops);
1419*8f000cacSChristoph Hellwig }
1420*8f000cacSChristoph Hellwig 
1421*8f000cacSChristoph Hellwig static void __exit nvmet_rdma_exit(void)
1422*8f000cacSChristoph Hellwig {
1423*8f000cacSChristoph Hellwig 	struct nvmet_rdma_queue *queue;
1424*8f000cacSChristoph Hellwig 
1425*8f000cacSChristoph Hellwig 	nvmet_unregister_transport(&nvmet_rdma_ops);
1426*8f000cacSChristoph Hellwig 
1427*8f000cacSChristoph Hellwig 	flush_scheduled_work();
1428*8f000cacSChristoph Hellwig 
1429*8f000cacSChristoph Hellwig 	mutex_lock(&nvmet_rdma_queue_mutex);
1430*8f000cacSChristoph Hellwig 	while ((queue = list_first_entry_or_null(&nvmet_rdma_queue_list,
1431*8f000cacSChristoph Hellwig 			struct nvmet_rdma_queue, queue_list))) {
1432*8f000cacSChristoph Hellwig 		list_del_init(&queue->queue_list);
1433*8f000cacSChristoph Hellwig 
1434*8f000cacSChristoph Hellwig 		mutex_unlock(&nvmet_rdma_queue_mutex);
1435*8f000cacSChristoph Hellwig 		__nvmet_rdma_queue_disconnect(queue);
1436*8f000cacSChristoph Hellwig 		mutex_lock(&nvmet_rdma_queue_mutex);
1437*8f000cacSChristoph Hellwig 	}
1438*8f000cacSChristoph Hellwig 	mutex_unlock(&nvmet_rdma_queue_mutex);
1439*8f000cacSChristoph Hellwig 
1440*8f000cacSChristoph Hellwig 	flush_scheduled_work();
1441*8f000cacSChristoph Hellwig 	ida_destroy(&nvmet_rdma_queue_ida);
1442*8f000cacSChristoph Hellwig }
1443*8f000cacSChristoph Hellwig 
1444*8f000cacSChristoph Hellwig module_init(nvmet_rdma_init);
1445*8f000cacSChristoph Hellwig module_exit(nvmet_rdma_exit);
1446*8f000cacSChristoph Hellwig 
1447*8f000cacSChristoph Hellwig MODULE_LICENSE("GPL v2");
1448*8f000cacSChristoph Hellwig MODULE_ALIAS("nvmet-transport-1"); /* 1 == NVMF_TRTYPE_RDMA */
1449