Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Shared Memory Communications over RDMA (SMC-R) and RoCE
  4 *
  5 * Work Requests exploiting Infiniband API
  6 *
  7 * Work requests (WR) of type ib_post_send or ib_post_recv respectively
  8 * are submitted to either RC SQ or RC RQ respectively
  9 * (reliably connected send/receive queue)
 10 * and become work queue entries (WQEs).
 11 * While an SQ WR/WQE is pending, we track it until transmission completion.
 12 * Through a send or receive completion queue (CQ) respectively,
 13 * we get completion queue entries (CQEs) [aka work completions (WCs)].
 14 * Since the CQ callback is called from IRQ context, we split work by using
 15 * bottom halves implemented by tasklets.
 16 *
 17 * SMC uses this to exchange LLC (link layer control)
 18 * and CDC (connection data control) messages.
 19 *
 20 * Copyright IBM Corp. 2016
 21 *
 22 * Author(s):  Steffen Maier <maier@linux.vnet.ibm.com>
 23 */
 24
 25#include <linux/atomic.h>
 26#include <linux/hashtable.h>
 27#include <linux/wait.h>
 28#include <rdma/ib_verbs.h>
 29#include <asm/div64.h>
 30
 31#include "smc.h"
 32#include "smc_wr.h"
 33
 34#define SMC_WR_MAX_POLL_CQE 10	/* max. # of compl. queue elements in 1 poll */
 35
 36#define SMC_WR_RX_HASH_BITS 4
 37static DEFINE_HASHTABLE(smc_wr_rx_hash, SMC_WR_RX_HASH_BITS);
 38static DEFINE_SPINLOCK(smc_wr_rx_hash_lock);
 39
 40struct smc_wr_tx_pend {	/* control data for a pending send request */
 41	u64			wr_id;		/* work request id sent */
 42	smc_wr_tx_handler	handler;
 43	enum ib_wc_status	wc_status;	/* CQE status */
 44	struct smc_link		*link;
 45	u32			idx;
 46	struct smc_wr_tx_pend_priv priv;
 47};
 48
 49/******************************** send queue *********************************/
 50
 51/*------------------------------- completion --------------------------------*/
 52
 53static inline int smc_wr_tx_find_pending_index(struct smc_link *link, u64 wr_id)
 54{
 55	u32 i;
 56
 57	for (i = 0; i < link->wr_tx_cnt; i++) {
 58		if (link->wr_tx_pends[i].wr_id == wr_id)
 59			return i;
 60	}
 61	return link->wr_tx_cnt;
 62}
 63
 64static inline void smc_wr_tx_process_cqe(struct ib_wc *wc)
 65{
 66	struct smc_wr_tx_pend pnd_snd;
 67	struct smc_link *link;
 68	u32 pnd_snd_idx;
 69	int i;
 70
 71	link = wc->qp->qp_context;
 72
 73	if (wc->opcode == IB_WC_REG_MR) {
 74		if (wc->status)
 75			link->wr_reg_state = FAILED;
 76		else
 77			link->wr_reg_state = CONFIRMED;
 78		wake_up(&link->wr_reg_wait);
 79		return;
 80	}
 81
 82	pnd_snd_idx = smc_wr_tx_find_pending_index(link, wc->wr_id);
 83	if (pnd_snd_idx == link->wr_tx_cnt)
 84		return;
 85	link->wr_tx_pends[pnd_snd_idx].wc_status = wc->status;
 86	memcpy(&pnd_snd, &link->wr_tx_pends[pnd_snd_idx], sizeof(pnd_snd));
 87	/* clear the full struct smc_wr_tx_pend including .priv */
 88	memset(&link->wr_tx_pends[pnd_snd_idx], 0,
 89	       sizeof(link->wr_tx_pends[pnd_snd_idx]));
 90	memset(&link->wr_tx_bufs[pnd_snd_idx], 0,
 91	       sizeof(link->wr_tx_bufs[pnd_snd_idx]));
 92	if (!test_and_clear_bit(pnd_snd_idx, link->wr_tx_mask))
 93		return;
 94	if (wc->status) {
 95		struct smc_link_group *lgr;
 96
 97		for_each_set_bit(i, link->wr_tx_mask, link->wr_tx_cnt) {
 98			/* clear full struct smc_wr_tx_pend including .priv */
 99			memset(&link->wr_tx_pends[i], 0,
100			       sizeof(link->wr_tx_pends[i]));
101			memset(&link->wr_tx_bufs[i], 0,
102			       sizeof(link->wr_tx_bufs[i]));
103			clear_bit(i, link->wr_tx_mask);
104		}
105		/* terminate connections of this link group abnormally */
106		lgr = container_of(link, struct smc_link_group,
107				   lnk[SMC_SINGLE_LINK]);
108		smc_lgr_terminate(lgr);
109	}
110	if (pnd_snd.handler)
111		pnd_snd.handler(&pnd_snd.priv, link, wc->status);
112	wake_up(&link->wr_tx_wait);
113}
114
115static void smc_wr_tx_tasklet_fn(unsigned long data)
116{
117	struct smc_ib_device *dev = (struct smc_ib_device *)data;
118	struct ib_wc wc[SMC_WR_MAX_POLL_CQE];
119	int i = 0, rc;
120	int polled = 0;
121
122again:
123	polled++;
124	do {
125		memset(&wc, 0, sizeof(wc));
126		rc = ib_poll_cq(dev->roce_cq_send, SMC_WR_MAX_POLL_CQE, wc);
127		if (polled == 1) {
128			ib_req_notify_cq(dev->roce_cq_send,
129					 IB_CQ_NEXT_COMP |
130					 IB_CQ_REPORT_MISSED_EVENTS);
131		}
132		if (!rc)
133			break;
134		for (i = 0; i < rc; i++)
135			smc_wr_tx_process_cqe(&wc[i]);
136	} while (rc > 0);
137	if (polled == 1)
138		goto again;
139}
140
141void smc_wr_tx_cq_handler(struct ib_cq *ib_cq, void *cq_context)
142{
143	struct smc_ib_device *dev = (struct smc_ib_device *)cq_context;
144
145	tasklet_schedule(&dev->send_tasklet);
146}
147
148/*---------------------------- request submission ---------------------------*/
149
150static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)
151{
152	*idx = link->wr_tx_cnt;
153	for_each_clear_bit(*idx, link->wr_tx_mask, link->wr_tx_cnt) {
154		if (!test_and_set_bit(*idx, link->wr_tx_mask))
155			return 0;
156	}
157	*idx = link->wr_tx_cnt;
158	return -EBUSY;
159}
160
161/**
162 * smc_wr_tx_get_free_slot() - returns buffer for message assembly,
163 *			and sets info for pending transmit tracking
164 * @link:		Pointer to smc_link used to later send the message.
165 * @handler:		Send completion handler function pointer.
166 * @wr_buf:		Out value returns pointer to message buffer.
167 * @wr_pend_priv:	Out value returns pointer serving as handler context.
168 *
169 * Return: 0 on success, or -errno on error.
170 */
171int smc_wr_tx_get_free_slot(struct smc_link *link,
172			    smc_wr_tx_handler handler,
173			    struct smc_wr_buf **wr_buf,
174			    struct smc_wr_tx_pend_priv **wr_pend_priv)
175{
176	struct smc_wr_tx_pend *wr_pend;
177	u32 idx = link->wr_tx_cnt;
178	struct ib_send_wr *wr_ib;
179	u64 wr_id;
180	int rc;
181
182	*wr_buf = NULL;
183	*wr_pend_priv = NULL;
184	if (in_softirq()) {
185		rc = smc_wr_tx_get_free_slot_index(link, &idx);
186		if (rc)
187			return rc;
188	} else {
189		struct smc_link_group *lgr;
190
191		lgr = container_of(link, struct smc_link_group,
192				   lnk[SMC_SINGLE_LINK]);
193		rc = wait_event_timeout(
194			link->wr_tx_wait,
195			list_empty(&lgr->list) || /* lgr terminated */
196			(smc_wr_tx_get_free_slot_index(link, &idx) != -EBUSY),
197			SMC_WR_TX_WAIT_FREE_SLOT_TIME);
198		if (!rc) {
199			/* timeout - terminate connections */
200			smc_lgr_terminate(lgr);
201			return -EPIPE;
202		}
203		if (idx == link->wr_tx_cnt)
204			return -EPIPE;
205	}
206	wr_id = smc_wr_tx_get_next_wr_id(link);
207	wr_pend = &link->wr_tx_pends[idx];
208	wr_pend->wr_id = wr_id;
209	wr_pend->handler = handler;
210	wr_pend->link = link;
211	wr_pend->idx = idx;
212	wr_ib = &link->wr_tx_ibs[idx];
213	wr_ib->wr_id = wr_id;
214	*wr_buf = &link->wr_tx_bufs[idx];
215	*wr_pend_priv = &wr_pend->priv;
216	return 0;
217}
218
219int smc_wr_tx_put_slot(struct smc_link *link,
220		       struct smc_wr_tx_pend_priv *wr_pend_priv)
221{
222	struct smc_wr_tx_pend *pend;
223
224	pend = container_of(wr_pend_priv, struct smc_wr_tx_pend, priv);
225	if (pend->idx < link->wr_tx_cnt) {
226		/* clear the full struct smc_wr_tx_pend including .priv */
227		memset(&link->wr_tx_pends[pend->idx], 0,
228		       sizeof(link->wr_tx_pends[pend->idx]));
229		memset(&link->wr_tx_bufs[pend->idx], 0,
230		       sizeof(link->wr_tx_bufs[pend->idx]));
231		test_and_clear_bit(pend->idx, link->wr_tx_mask);
232		return 1;
233	}
234
235	return 0;
236}
237
238/* Send prepared WR slot via ib_post_send.
239 * @priv: pointer to smc_wr_tx_pend_priv identifying prepared message buffer
240 */
241int smc_wr_tx_send(struct smc_link *link, struct smc_wr_tx_pend_priv *priv)
242{
243	struct ib_send_wr *failed_wr = NULL;
244	struct smc_wr_tx_pend *pend;
245	int rc;
246
247	ib_req_notify_cq(link->smcibdev->roce_cq_send,
248			 IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
249	pend = container_of(priv, struct smc_wr_tx_pend, priv);
250	rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx],
251			  &failed_wr);
252	if (rc) {
253		struct smc_link_group *lgr =
254			container_of(link, struct smc_link_group,
255				     lnk[SMC_SINGLE_LINK]);
256
257		smc_wr_tx_put_slot(link, priv);
258		smc_lgr_terminate(lgr);
259	}
260	return rc;
261}
262
263/* Register a memory region and wait for result. */
264int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr)
265{
266	struct ib_send_wr *failed_wr = NULL;
267	int rc;
268
269	ib_req_notify_cq(link->smcibdev->roce_cq_send,
270			 IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
271	link->wr_reg_state = POSTED;
272	link->wr_reg.wr.wr_id = (u64)(uintptr_t)mr;
273	link->wr_reg.mr = mr;
274	link->wr_reg.key = mr->rkey;
275	failed_wr = &link->wr_reg.wr;
276	rc = ib_post_send(link->roce_qp, &link->wr_reg.wr, &failed_wr);
277	WARN_ON(failed_wr != &link->wr_reg.wr);
278	if (rc)
279		return rc;
280
281	rc = wait_event_interruptible_timeout(link->wr_reg_wait,
282					      (link->wr_reg_state != POSTED),
283					      SMC_WR_REG_MR_WAIT_TIME);
284	if (!rc) {
285		/* timeout - terminate connections */
286		struct smc_link_group *lgr;
287
288		lgr = container_of(link, struct smc_link_group,
289				   lnk[SMC_SINGLE_LINK]);
290		smc_lgr_terminate(lgr);
291		return -EPIPE;
292	}
293	if (rc == -ERESTARTSYS)
294		return -EINTR;
295	switch (link->wr_reg_state) {
296	case CONFIRMED:
297		rc = 0;
298		break;
299	case FAILED:
300		rc = -EIO;
301		break;
302	case POSTED:
303		rc = -EPIPE;
304		break;
305	}
306	return rc;
307}
308
309void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_tx_hdr_type,
310			     smc_wr_tx_filter filter,
311			     smc_wr_tx_dismisser dismisser,
312			     unsigned long data)
313{
314	struct smc_wr_tx_pend_priv *tx_pend;
315	struct smc_wr_rx_hdr *wr_tx;
316	int i;
317
318	for_each_set_bit(i, link->wr_tx_mask, link->wr_tx_cnt) {
319		wr_tx = (struct smc_wr_rx_hdr *)&link->wr_tx_bufs[i];
320		if (wr_tx->type != wr_tx_hdr_type)
321			continue;
322		tx_pend = &link->wr_tx_pends[i].priv;
323		if (filter(tx_pend, data))
324			dismisser(tx_pend);
325	}
326}
327
328/****************************** receive queue ********************************/
329
330int smc_wr_rx_register_handler(struct smc_wr_rx_handler *handler)
331{
332	struct smc_wr_rx_handler *h_iter;
333	int rc = 0;
334
335	spin_lock(&smc_wr_rx_hash_lock);
336	hash_for_each_possible(smc_wr_rx_hash, h_iter, list, handler->type) {
337		if (h_iter->type == handler->type) {
338			rc = -EEXIST;
339			goto out_unlock;
340		}
341	}
342	hash_add(smc_wr_rx_hash, &handler->list, handler->type);
343out_unlock:
344	spin_unlock(&smc_wr_rx_hash_lock);
345	return rc;
346}
347
348/* Demultiplex a received work request based on the message type to its handler.
349 * Relies on smc_wr_rx_hash having been completely filled before any IB WRs,
350 * and not being modified any more afterwards so we don't need to lock it.
351 */
352static inline void smc_wr_rx_demultiplex(struct ib_wc *wc)
353{
354	struct smc_link *link = (struct smc_link *)wc->qp->qp_context;
355	struct smc_wr_rx_handler *handler;
356	struct smc_wr_rx_hdr *wr_rx;
357	u64 temp_wr_id;
358	u32 index;
359
360	if (wc->byte_len < sizeof(*wr_rx))
361		return; /* short message */
362	temp_wr_id = wc->wr_id;
363	index = do_div(temp_wr_id, link->wr_rx_cnt);
364	wr_rx = (struct smc_wr_rx_hdr *)&link->wr_rx_bufs[index];
365	hash_for_each_possible(smc_wr_rx_hash, handler, list, wr_rx->type) {
366		if (handler->type == wr_rx->type)
367			handler->handler(wc, wr_rx);
368	}
369}
370
371static inline void smc_wr_rx_process_cqes(struct ib_wc wc[], int num)
372{
373	struct smc_link *link;
374	int i;
375
376	for (i = 0; i < num; i++) {
377		link = wc[i].qp->qp_context;
378		if (wc[i].status == IB_WC_SUCCESS) {
379			smc_wr_rx_demultiplex(&wc[i]);
380			smc_wr_rx_post(link); /* refill WR RX */
381		} else {
382			struct smc_link_group *lgr;
383
384			/* handle status errors */
385			switch (wc[i].status) {
386			case IB_WC_RETRY_EXC_ERR:
387			case IB_WC_RNR_RETRY_EXC_ERR:
388			case IB_WC_WR_FLUSH_ERR:
389				/* terminate connections of this link group
390				 * abnormally
391				 */
392				lgr = container_of(link, struct smc_link_group,
393						   lnk[SMC_SINGLE_LINK]);
394				smc_lgr_terminate(lgr);
395				break;
396			default:
397				smc_wr_rx_post(link); /* refill WR RX */
398				break;
399			}
400		}
401	}
402}
403
404static void smc_wr_rx_tasklet_fn(unsigned long data)
405{
406	struct smc_ib_device *dev = (struct smc_ib_device *)data;
407	struct ib_wc wc[SMC_WR_MAX_POLL_CQE];
408	int polled = 0;
409	int rc;
410
411again:
412	polled++;
413	do {
414		memset(&wc, 0, sizeof(wc));
415		rc = ib_poll_cq(dev->roce_cq_recv, SMC_WR_MAX_POLL_CQE, wc);
416		if (polled == 1) {
417			ib_req_notify_cq(dev->roce_cq_recv,
418					 IB_CQ_SOLICITED_MASK
419					 | IB_CQ_REPORT_MISSED_EVENTS);
420		}
421		if (!rc)
422			break;
423		smc_wr_rx_process_cqes(&wc[0], rc);
424	} while (rc > 0);
425	if (polled == 1)
426		goto again;
427}
428
429void smc_wr_rx_cq_handler(struct ib_cq *ib_cq, void *cq_context)
430{
431	struct smc_ib_device *dev = (struct smc_ib_device *)cq_context;
432
433	tasklet_schedule(&dev->recv_tasklet);
434}
435
436int smc_wr_rx_post_init(struct smc_link *link)
437{
438	u32 i;
439	int rc = 0;
440
441	for (i = 0; i < link->wr_rx_cnt; i++)
442		rc = smc_wr_rx_post(link);
443	return rc;
444}
445
446/***************************** init, exit, misc ******************************/
447
448void smc_wr_remember_qp_attr(struct smc_link *lnk)
449{
450	struct ib_qp_attr *attr = &lnk->qp_attr;
451	struct ib_qp_init_attr init_attr;
452
453	memset(attr, 0, sizeof(*attr));
454	memset(&init_attr, 0, sizeof(init_attr));
455	ib_query_qp(lnk->roce_qp, attr,
456		    IB_QP_STATE |
457		    IB_QP_CUR_STATE |
458		    IB_QP_PKEY_INDEX |
459		    IB_QP_PORT |
460		    IB_QP_QKEY |
461		    IB_QP_AV |
462		    IB_QP_PATH_MTU |
463		    IB_QP_TIMEOUT |
464		    IB_QP_RETRY_CNT |
465		    IB_QP_RNR_RETRY |
466		    IB_QP_RQ_PSN |
467		    IB_QP_ALT_PATH |
468		    IB_QP_MIN_RNR_TIMER |
469		    IB_QP_SQ_PSN |
470		    IB_QP_PATH_MIG_STATE |
471		    IB_QP_CAP |
472		    IB_QP_DEST_QPN,
473		    &init_attr);
474
475	lnk->wr_tx_cnt = min_t(size_t, SMC_WR_BUF_CNT,
476			       lnk->qp_attr.cap.max_send_wr);
477	lnk->wr_rx_cnt = min_t(size_t, SMC_WR_BUF_CNT * 3,
478			       lnk->qp_attr.cap.max_recv_wr);
479}
480
481static void smc_wr_init_sge(struct smc_link *lnk)
482{
483	u32 i;
484
485	for (i = 0; i < lnk->wr_tx_cnt; i++) {
486		lnk->wr_tx_sges[i].addr =
487			lnk->wr_tx_dma_addr + i * SMC_WR_BUF_SIZE;
488		lnk->wr_tx_sges[i].length = SMC_WR_TX_SIZE;
489		lnk->wr_tx_sges[i].lkey = lnk->roce_pd->local_dma_lkey;
490		lnk->wr_tx_ibs[i].next = NULL;
491		lnk->wr_tx_ibs[i].sg_list = &lnk->wr_tx_sges[i];
492		lnk->wr_tx_ibs[i].num_sge = 1;
493		lnk->wr_tx_ibs[i].opcode = IB_WR_SEND;
494		lnk->wr_tx_ibs[i].send_flags =
495			IB_SEND_SIGNALED | IB_SEND_SOLICITED;
496	}
497	for (i = 0; i < lnk->wr_rx_cnt; i++) {
498		lnk->wr_rx_sges[i].addr =
499			lnk->wr_rx_dma_addr + i * SMC_WR_BUF_SIZE;
500		lnk->wr_rx_sges[i].length = SMC_WR_BUF_SIZE;
501		lnk->wr_rx_sges[i].lkey = lnk->roce_pd->local_dma_lkey;
502		lnk->wr_rx_ibs[i].next = NULL;
503		lnk->wr_rx_ibs[i].sg_list = &lnk->wr_rx_sges[i];
504		lnk->wr_rx_ibs[i].num_sge = 1;
505	}
506	lnk->wr_reg.wr.next = NULL;
507	lnk->wr_reg.wr.num_sge = 0;
508	lnk->wr_reg.wr.send_flags = IB_SEND_SIGNALED;
509	lnk->wr_reg.wr.opcode = IB_WR_REG_MR;
510	lnk->wr_reg.access = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE;
511}
512
513void smc_wr_free_link(struct smc_link *lnk)
514{
515	struct ib_device *ibdev;
516
517	memset(lnk->wr_tx_mask, 0,
518	       BITS_TO_LONGS(SMC_WR_BUF_CNT) * sizeof(*lnk->wr_tx_mask));
519
520	if (!lnk->smcibdev)
521		return;
522	ibdev = lnk->smcibdev->ibdev;
523
524	if (lnk->wr_rx_dma_addr) {
525		ib_dma_unmap_single(ibdev, lnk->wr_rx_dma_addr,
526				    SMC_WR_BUF_SIZE * lnk->wr_rx_cnt,
527				    DMA_FROM_DEVICE);
528		lnk->wr_rx_dma_addr = 0;
529	}
530	if (lnk->wr_tx_dma_addr) {
531		ib_dma_unmap_single(ibdev, lnk->wr_tx_dma_addr,
532				    SMC_WR_BUF_SIZE * lnk->wr_tx_cnt,
533				    DMA_TO_DEVICE);
534		lnk->wr_tx_dma_addr = 0;
535	}
536}
537
538void smc_wr_free_link_mem(struct smc_link *lnk)
539{
540	kfree(lnk->wr_tx_pends);
541	lnk->wr_tx_pends = NULL;
542	kfree(lnk->wr_tx_mask);
543	lnk->wr_tx_mask = NULL;
544	kfree(lnk->wr_tx_sges);
545	lnk->wr_tx_sges = NULL;
546	kfree(lnk->wr_rx_sges);
547	lnk->wr_rx_sges = NULL;
548	kfree(lnk->wr_rx_ibs);
549	lnk->wr_rx_ibs = NULL;
550	kfree(lnk->wr_tx_ibs);
551	lnk->wr_tx_ibs = NULL;
552	kfree(lnk->wr_tx_bufs);
553	lnk->wr_tx_bufs = NULL;
554	kfree(lnk->wr_rx_bufs);
555	lnk->wr_rx_bufs = NULL;
556}
557
558int smc_wr_alloc_link_mem(struct smc_link *link)
559{
560	/* allocate link related memory */
561	link->wr_tx_bufs = kcalloc(SMC_WR_BUF_CNT, SMC_WR_BUF_SIZE, GFP_KERNEL);
562	if (!link->wr_tx_bufs)
563		goto no_mem;
564	link->wr_rx_bufs = kcalloc(SMC_WR_BUF_CNT * 3, SMC_WR_BUF_SIZE,
565				   GFP_KERNEL);
566	if (!link->wr_rx_bufs)
567		goto no_mem_wr_tx_bufs;
568	link->wr_tx_ibs = kcalloc(SMC_WR_BUF_CNT, sizeof(link->wr_tx_ibs[0]),
569				  GFP_KERNEL);
570	if (!link->wr_tx_ibs)
571		goto no_mem_wr_rx_bufs;
572	link->wr_rx_ibs = kcalloc(SMC_WR_BUF_CNT * 3,
573				  sizeof(link->wr_rx_ibs[0]),
574				  GFP_KERNEL);
575	if (!link->wr_rx_ibs)
576		goto no_mem_wr_tx_ibs;
577	link->wr_tx_sges = kcalloc(SMC_WR_BUF_CNT, sizeof(link->wr_tx_sges[0]),
578				   GFP_KERNEL);
579	if (!link->wr_tx_sges)
580		goto no_mem_wr_rx_ibs;
581	link->wr_rx_sges = kcalloc(SMC_WR_BUF_CNT * 3,
582				   sizeof(link->wr_rx_sges[0]),
583				   GFP_KERNEL);
584	if (!link->wr_rx_sges)
585		goto no_mem_wr_tx_sges;
586	link->wr_tx_mask = kzalloc(
587		BITS_TO_LONGS(SMC_WR_BUF_CNT) * sizeof(*link->wr_tx_mask),
588		GFP_KERNEL);
589	if (!link->wr_tx_mask)
590		goto no_mem_wr_rx_sges;
591	link->wr_tx_pends = kcalloc(SMC_WR_BUF_CNT,
592				    sizeof(link->wr_tx_pends[0]),
593				    GFP_KERNEL);
594	if (!link->wr_tx_pends)
595		goto no_mem_wr_tx_mask;
596	return 0;
597
598no_mem_wr_tx_mask:
599	kfree(link->wr_tx_mask);
600no_mem_wr_rx_sges:
601	kfree(link->wr_rx_sges);
602no_mem_wr_tx_sges:
603	kfree(link->wr_tx_sges);
604no_mem_wr_rx_ibs:
605	kfree(link->wr_rx_ibs);
606no_mem_wr_tx_ibs:
607	kfree(link->wr_tx_ibs);
608no_mem_wr_rx_bufs:
609	kfree(link->wr_rx_bufs);
610no_mem_wr_tx_bufs:
611	kfree(link->wr_tx_bufs);
612no_mem:
613	return -ENOMEM;
614}
615
616void smc_wr_remove_dev(struct smc_ib_device *smcibdev)
617{
618	tasklet_kill(&smcibdev->recv_tasklet);
619	tasklet_kill(&smcibdev->send_tasklet);
620}
621
622void smc_wr_add_dev(struct smc_ib_device *smcibdev)
623{
624	tasklet_init(&smcibdev->recv_tasklet, smc_wr_rx_tasklet_fn,
625		     (unsigned long)smcibdev);
626	tasklet_init(&smcibdev->send_tasklet, smc_wr_tx_tasklet_fn,
627		     (unsigned long)smcibdev);
628}
629
630int smc_wr_create_link(struct smc_link *lnk)
631{
632	struct ib_device *ibdev = lnk->smcibdev->ibdev;
633	int rc = 0;
634
635	smc_wr_tx_set_wr_id(&lnk->wr_tx_id, 0);
636	lnk->wr_rx_id = 0;
637	lnk->wr_rx_dma_addr = ib_dma_map_single(
638		ibdev, lnk->wr_rx_bufs,	SMC_WR_BUF_SIZE * lnk->wr_rx_cnt,
639		DMA_FROM_DEVICE);
640	if (ib_dma_mapping_error(ibdev, lnk->wr_rx_dma_addr)) {
641		lnk->wr_rx_dma_addr = 0;
642		rc = -EIO;
643		goto out;
644	}
645	lnk->wr_tx_dma_addr = ib_dma_map_single(
646		ibdev, lnk->wr_tx_bufs,	SMC_WR_BUF_SIZE * lnk->wr_tx_cnt,
647		DMA_TO_DEVICE);
648	if (ib_dma_mapping_error(ibdev, lnk->wr_tx_dma_addr)) {
649		rc = -EIO;
650		goto dma_unmap;
651	}
652	smc_wr_init_sge(lnk);
653	memset(lnk->wr_tx_mask, 0,
654	       BITS_TO_LONGS(SMC_WR_BUF_CNT) * sizeof(*lnk->wr_tx_mask));
655	init_waitqueue_head(&lnk->wr_tx_wait);
656	init_waitqueue_head(&lnk->wr_reg_wait);
657	return rc;
658
659dma_unmap:
660	ib_dma_unmap_single(ibdev, lnk->wr_rx_dma_addr,
661			    SMC_WR_BUF_SIZE * lnk->wr_rx_cnt,
662			    DMA_FROM_DEVICE);
663	lnk->wr_rx_dma_addr = 0;
664out:
665	return rc;
666}