Ejemplo n.º 1
0
Archivo: verbs.c Proyecto: 274914765/C
/*
 * Unregister and destroy buffer memory. Need to deal with
 * partial initialization, so it's callable from failed create.
 * Must be called before destroying endpoint, as registrations
 * reference it.
 */
void
rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
{
    int rc, i;
    struct rpcrdma_ia *ia = rdmab_to_ia(buf);

    /* clean up in reverse order from create
     *   1.  recv mr memory (mr free, then kfree)
     *   1a. bind mw memory
     *   2.  send mr memory (mr free, then kfree)
     *   3.  padding (if any) [moved to rpcrdma_ep_destroy]
     *   4.  arrays
     */
    dprintk("RPC:       %s: entering\n", __func__);

    for (i = 0; i < buf->rb_max_requests; i++) {
        if (buf->rb_recv_bufs && buf->rb_recv_bufs[i]) {
            rpcrdma_deregister_internal(ia,
                    buf->rb_recv_bufs[i]->rr_handle,
                    &buf->rb_recv_bufs[i]->rr_iov);
            kfree(buf->rb_recv_bufs[i]);
        }
        if (buf->rb_send_bufs && buf->rb_send_bufs[i]) {
            while (!list_empty(&buf->rb_mws)) {
                struct rpcrdma_mw *r;
                r = list_entry(buf->rb_mws.next,
                    struct rpcrdma_mw, mw_list);
                list_del(&r->mw_list);
                switch (ia->ri_memreg_strategy) {
                case RPCRDMA_MTHCAFMR:
                    rc = ib_dealloc_fmr(r->r.fmr);
                    if (rc)
                        dprintk("RPC:       %s:"
                            " ib_dealloc_fmr"
                            " failed %i\n",
                            __func__, rc);
                    break;
                case RPCRDMA_MEMWINDOWS_ASYNC:
                case RPCRDMA_MEMWINDOWS:
                    rc = ib_dealloc_mw(r->r.mw);
                    if (rc)
                        dprintk("RPC:       %s:"
                            " ib_dealloc_mw"
                            " failed %i\n",
                            __func__, rc);
                    break;
                default:
                    break;
                }
            }
            rpcrdma_deregister_internal(ia,
                    buf->rb_send_bufs[i]->rl_handle,
                    &buf->rb_send_bufs[i]->rl_iov);
            kfree(buf->rb_send_bufs[i]);
        }
    }

    kfree(buf->rb_pool);
}
Ejemplo n.º 2
0
/*
 * rpcrdma_ep_destroy
 *
 * Disconnect and destroy endpoint. After this, the only
 * valid operations on the ep are to free it (if dynamically
 * allocated) or re-create it.
 *
 * The caller's error handling must be sure to not leak the endpoint
 * if this function fails.
 */
int
rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
{
	int rc;

	dprintk("RPC:       %s: entering, connected is %d\n",
		__func__, ep->rep_connected);

	if (ia->ri_id->qp) {
		rc = rpcrdma_ep_disconnect(ep, ia);
		if (rc)
			dprintk("RPC:       %s: rpcrdma_ep_disconnect"
				" returned %i\n", __func__, rc);
		rdma_destroy_qp(ia->ri_id);
		ia->ri_id->qp = NULL;
	}

	/* padding - could be done in rpcrdma_buffer_destroy... */
	if (ep->rep_pad_mr) {
		rpcrdma_deregister_internal(ia, ep->rep_pad_mr, &ep->rep_pad);
		ep->rep_pad_mr = NULL;
	}

	rpcrdma_clean_cq(ep->rep_cq);
	rc = ib_destroy_cq(ep->rep_cq);
	if (rc)
		dprintk("RPC:       %s: ib_destroy_cq returned %i\n",
			__func__, rc);

	return rc;
}