void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_event *event)
{
	const struct rds_ib_connect_private *dp = NULL;
	struct rds_ib_connection *ic = conn->c_transport_data;
	struct ib_qp_attr qp_attr;
	int err;

	if (event->param.conn.private_data_len >= sizeof(*dp)) {
		dp = event->param.conn.private_data;

		
		if (dp->dp_protocol_major) {
			rds_ib_set_protocol(conn,
				RDS_PROTOCOL(dp->dp_protocol_major,
				dp->dp_protocol_minor));
			rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
		}
	}

	if (conn->c_version < RDS_PROTOCOL(3,1)) {
		printk(KERN_NOTICE "RDS/IB: Connection to %pI4 version %u.%u failed,"
		       " no longer supported\n",
		       &conn->c_faddr,
		       RDS_PROTOCOL_MAJOR(conn->c_version),
		       RDS_PROTOCOL_MINOR(conn->c_version));
		rds_conn_destroy(conn);
		return;
	} else {
		printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
		       &conn->c_faddr,
		       RDS_PROTOCOL_MAJOR(conn->c_version),
		       RDS_PROTOCOL_MINOR(conn->c_version),
		       ic->i_flowctl ? ", flow control" : "");
	}

	rds_ib_send_init_ring(ic);
	rds_ib_recv_init_ring(ic);
	rds_ib_recv_refill(conn, 1);

	
	rds_ib_tune_rnr(ic, &qp_attr);

	qp_attr.qp_state = IB_QPS_RTS;
	err = ib_modify_qp(ic->i_cm_id->qp, &qp_attr, IB_QP_STATE);
	if (err)
		printk(KERN_NOTICE "ib_modify_qp(IB_QP_STATE, RTS): err=%d\n", err);

	
	err = rds_ib_update_ipaddr(ic->rds_ibdev, conn->c_laddr);
	if (err)
		printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n",
			err);

	if (dp && dp->dp_ack_seq)
		rds_send_drop_acked(conn, be64_to_cpu(dp->dp_ack_seq), NULL);

	rds_connect_complete(conn);
}
Example #2
0
static void rds_iw_cm_fill_conn_param(struct rds_connection *conn,
			struct rdma_conn_param *conn_param,
			struct rds_iw_connect_private *dp,
			u32 protocol_version)
{
	struct rds_iw_connection *ic = conn->c_transport_data;

	memset(conn_param, 0, sizeof(struct rdma_conn_param));
	/* XXX tune these? */
	conn_param->responder_resources = 1;
	conn_param->initiator_depth = 1;

	if (dp) {
		memset(dp, 0, sizeof(*dp));
		dp->dp_saddr = conn->c_laddr;
		dp->dp_daddr = conn->c_faddr;
		dp->dp_protocol_major = RDS_PROTOCOL_MAJOR(protocol_version);
		dp->dp_protocol_minor = RDS_PROTOCOL_MINOR(protocol_version);
		dp->dp_protocol_minor_mask = cpu_to_be16(RDS_IW_SUPPORTED_PROTOCOLS);
		dp->dp_ack_seq = rds_iw_piggyb_ack(ic);

		/* Advertise flow control */
		if (ic->i_flowctl) {
			unsigned int credits;

			credits = IB_GET_POST_CREDITS(atomic_read(&ic->i_credits));
			dp->dp_credit = cpu_to_be32(credits);
			atomic_sub(IB_SET_POST_CREDITS(credits), &ic->i_credits);
		}

		conn_param->private_data = dp;
		conn_param->private_data_len = sizeof(*dp);
	}
}
Example #3
0
/*
 * Connection established.
 * We get here for both outgoing and incoming connection.
 */
void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_event *event)
{
	const struct rds_ib_connect_private *dp = NULL;
	struct rds_ib_connection *ic = conn->c_transport_data;
	struct rds_ib_device *rds_ibdev;
	struct ib_qp_attr qp_attr;
	int err;

	if (event->param.conn.private_data_len >= sizeof(*dp)) {
		dp = event->param.conn.private_data;

		/* make sure it isn't empty data */
		if (dp->dp_protocol_major) {
			rds_ib_set_protocol(conn,
				RDS_PROTOCOL(dp->dp_protocol_major,
				dp->dp_protocol_minor));
			rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
		}
	}

	printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
			&conn->c_faddr,
			RDS_PROTOCOL_MAJOR(conn->c_version),
			RDS_PROTOCOL_MINOR(conn->c_version),
			ic->i_flowctl ? ", flow control" : "");

	/*
	 * Init rings and fill recv. this needs to wait until protocol negotiation
	 * is complete, since ring layout is different from 3.0 to 3.1.
	 */
	rds_ib_send_init_ring(ic);
	rds_ib_recv_init_ring(ic);
	/* Post receive buffers - as a side effect, this will update
	 * the posted credit count. */
	rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1);

	/* Tune RNR behavior */
	rds_ib_tune_rnr(ic, &qp_attr);

	qp_attr.qp_state = IB_QPS_RTS;
	err = ib_modify_qp(ic->i_cm_id->qp, &qp_attr, IB_QP_STATE);
	if (err)
		printk(KERN_NOTICE "ib_modify_qp(IB_QP_STATE, RTS): err=%d\n", err);

	/* update ib_device with this local ipaddr & conn */
	rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client);
	err = rds_ib_update_ipaddr(rds_ibdev, conn->c_laddr);
	if (err)
		printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n", err);
	rds_ib_add_conn(rds_ibdev, conn);

	/* If the peer gave us the last packet it saw, process this as if
	 * we had received a regular ACK. */
	if (dp && dp->dp_ack_seq)
		rds_send_drop_acked(conn, be64_to_cpu(dp->dp_ack_seq), NULL);

	rds_connect_complete(conn);
}
Example #4
0
static void
rdsv3_ib_cm_fill_conn_param(struct rdsv3_connection *conn,
    struct rdma_conn_param *conn_param,
    struct rdsv3_ib_connect_private *dp,
    uint32_t protocol_version,
    uint32_t max_responder_resources,
    uint32_t max_initiator_depth)
{
	struct rdsv3_ib_connection *ic = conn->c_transport_data;
	struct rdsv3_ib_device *rds_ibdev;

	RDSV3_DPRINTF2("rdsv3_ib_cm_fill_conn_param",
	    "Enter conn: %p conn_param: %p private: %p version: %d",
	    conn, conn_param, dp, protocol_version);

	(void) memset(conn_param, 0, sizeof (struct rdma_conn_param));

	rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rdsv3_ib_client);

	conn_param->responder_resources =
	    MIN(rds_ibdev->max_responder_resources, max_responder_resources);
	conn_param->initiator_depth =
	    MIN(rds_ibdev->max_initiator_depth, max_initiator_depth);
	conn_param->retry_count = min(rdsv3_ib_retry_count, 7);
	conn_param->rnr_retry_count = 7;

	if (dp) {
		(void) memset(dp, 0, sizeof (*dp));
		dp->dp_saddr = conn->c_laddr;
		dp->dp_daddr = conn->c_faddr;
		dp->dp_protocol_major = RDS_PROTOCOL_MAJOR(protocol_version);
		dp->dp_protocol_minor = RDS_PROTOCOL_MINOR(protocol_version);
		dp->dp_protocol_minor_mask =
		    htons(RDSV3_IB_SUPPORTED_PROTOCOLS);
		dp->dp_ack_seq = rdsv3_ib_piggyb_ack(ic);

		/* Advertise flow control */
		if (ic->i_flowctl) {
			unsigned int credits;

			credits = IB_GET_POST_CREDITS(
			    atomic_get(&ic->i_credits));
			dp->dp_credit = htonl(credits);
			atomic_add_32(&ic->i_credits,
			    -IB_SET_POST_CREDITS(credits));
		}

		conn_param->private_data = dp;
		conn_param->private_data_len = sizeof (*dp);
	}

	RDSV3_DPRINTF2("rdsv3_ib_cm_fill_conn_param",
	    "Return conn: %p conn_param: %p private: %p version: %d",
	    conn, conn_param, dp, protocol_version);
}
Example #5
0
static void rds_ib_cm_fill_conn_param(struct rds_connection *conn,
			struct rdma_conn_param *conn_param,
			struct rds_ib_connect_private *dp,
			u32 protocol_version,
			u32 max_responder_resources,
			u32 max_initiator_depth)
{
	struct rds_ib_connection *ic = conn->c_transport_data;
	struct rds_ib_device *rds_ibdev = ic->rds_ibdev;

	memset(conn_param, 0, sizeof(struct rdma_conn_param));

	conn_param->responder_resources =
		min_t(u32, rds_ibdev->max_responder_resources, max_responder_resources);
	conn_param->initiator_depth =
		min_t(u32, rds_ibdev->max_initiator_depth, max_initiator_depth);
	conn_param->retry_count = min_t(unsigned int, rds_ib_retry_count, 7);
	conn_param->rnr_retry_count = 7;

	if (dp) {
		memset(dp, 0, sizeof(*dp));
		dp->dp_saddr = conn->c_laddr;
		dp->dp_daddr = conn->c_faddr;
		dp->dp_protocol_major = RDS_PROTOCOL_MAJOR(protocol_version);
		dp->dp_protocol_minor = RDS_PROTOCOL_MINOR(protocol_version);
		dp->dp_protocol_minor_mask = cpu_to_be16(RDS_IB_SUPPORTED_PROTOCOLS);
		dp->dp_ack_seq = cpu_to_be64(rds_ib_piggyb_ack(ic));

		/* Advertise flow control */
		if (ic->i_flowctl) {
			unsigned int credits;

			credits = IB_GET_POST_CREDITS(atomic_read(&ic->i_credits));
			dp->dp_credit = cpu_to_be32(credits);
			atomic_sub(IB_SET_POST_CREDITS(credits), &ic->i_credits);
		}

		conn_param->private_data = dp;
		conn_param->private_data_len = sizeof(*dp);
	}
}
Example #6
0
/*
 * Connection established.
 * We get here for both outgoing and incoming connection.
 */
void rds_iw_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_event *event)
{
	const struct rds_iw_connect_private *dp = NULL;
	struct rds_iw_connection *ic = conn->c_transport_data;
	struct rds_iw_device *rds_iwdev;
	int err;

	if (event->param.conn.private_data_len) {
		dp = event->param.conn.private_data;

		rds_iw_set_protocol(conn,
				RDS_PROTOCOL(dp->dp_protocol_major,
					dp->dp_protocol_minor));
		rds_iw_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
	}

	/* update ib_device with this local ipaddr & conn */
	rds_iwdev = ib_get_client_data(ic->i_cm_id->device, &rds_iw_client);
	err = rds_iw_update_cm_id(rds_iwdev, ic->i_cm_id);
	if (err)
		printk(KERN_ERR "rds_iw_update_ipaddr failed (%d)\n", err);
	rds_iw_add_conn(rds_iwdev, conn);

	/* If the peer gave us the last packet it saw, process this as if
	 * we had received a regular ACK. */
	if (dp && dp->dp_ack_seq)
		rds_send_drop_acked(conn, be64_to_cpu(dp->dp_ack_seq), NULL);

	printk(KERN_NOTICE "RDS/IW: connected to %pI4<->%pI4 version %u.%u%s\n",
			&conn->c_laddr, &conn->c_faddr,
			RDS_PROTOCOL_MAJOR(conn->c_version),
			RDS_PROTOCOL_MINOR(conn->c_version),
			ic->i_flowctl ? ", flow control" : "");

	rds_connect_complete(conn);
}
Example #7
0
/*
 * Connection established.
 * We get here for both outgoing and incoming connection.
 */
void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_event *event)
{
	const struct rds_ib_connect_private *dp = NULL;
	struct rds_ib_connection *ic = conn->c_transport_data;
	struct ib_qp_attr qp_attr;
	int err;

	if (event->param.conn.private_data_len >= sizeof(*dp)) {
		dp = event->param.conn.private_data;

		/* make sure it isn't empty data */
		if (dp->dp_protocol_major) {
			rds_ib_set_protocol(conn,
				RDS_PROTOCOL(dp->dp_protocol_major,
				dp->dp_protocol_minor));
			rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
		}
	}

	if (conn->c_version < RDS_PROTOCOL(3, 1)) {
		printk(KERN_NOTICE "RDS/IB: Connection to %pI4 version %u.%u failed,"
		       " no longer supported\n",
		       &conn->c_faddr,
		       RDS_PROTOCOL_MAJOR(conn->c_version),
		       RDS_PROTOCOL_MINOR(conn->c_version));
		rds_conn_destroy(conn);
		return;
	} else {
		printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
		       &conn->c_faddr,
		       RDS_PROTOCOL_MAJOR(conn->c_version),
		       RDS_PROTOCOL_MINOR(conn->c_version),
		       ic->i_flowctl ? ", flow control" : "");
	}

	/*
	 * Init rings and fill recv. this needs to wait until protocol negotiation
	 * is complete, since ring layout is different from 3.0 to 3.1.
	 */
	rds_ib_send_init_ring(ic);
	rds_ib_recv_init_ring(ic);
	/* Post receive buffers - as a side effect, this will update
	 * the posted credit count. */
	rds_ib_recv_refill(conn, 1, GFP_KERNEL);

	/* Tune RNR behavior */
	rds_ib_tune_rnr(ic, &qp_attr);

	qp_attr.qp_state = IB_QPS_RTS;
	err = ib_modify_qp(ic->i_cm_id->qp, &qp_attr, IB_QP_STATE);
	if (err)
		printk(KERN_NOTICE "ib_modify_qp(IB_QP_STATE, RTS): err=%d\n", err);

	/* update ib_device with this local ipaddr */
	err = rds_ib_update_ipaddr(ic->rds_ibdev, conn->c_laddr);
	if (err)
		printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n",
			err);

	/* If the peer gave us the last packet it saw, process this as if
	 * we had received a regular ACK. */
	if (dp) {
		/* dp structure start is not guaranteed to be 8 bytes aligned.
		 * Since dp_ack_seq is 64-bit extended load operations can be
		 * used so go through get_unaligned to avoid unaligned errors.
		 */
		__be64 dp_ack_seq = get_unaligned(&dp->dp_ack_seq);

		if (dp_ack_seq)
			rds_send_drop_acked(conn, be64_to_cpu(dp_ack_seq),
					    NULL);
	}

	rds_connect_complete(conn);
}
Example #8
0
/*
 * Connection established.
 * We get here for both outgoing and incoming connection.
 */
void
rdsv3_ib_cm_connect_complete(struct rdsv3_connection *conn,
    struct rdma_cm_event *event)
{
	const struct rdsv3_ib_connect_private *dp = NULL;
	struct rdsv3_ib_connection *ic = conn->c_transport_data;
	struct rdsv3_ib_device *rds_ibdev =
	    ib_get_client_data(ic->i_cm_id->device, &rdsv3_ib_client);
	struct ib_qp_attr qp_attr;
	int err;

	RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
	    "Enter conn: %p event: %p", conn, event);

	if (event->param.conn.private_data_len >= sizeof (*dp)) {
		dp = event->param.conn.private_data;

		/* make sure it isn't empty data */
		if (dp->dp_protocol_major) {
			rdsv3_ib_set_protocol(conn,
			    RDS_PROTOCOL(dp->dp_protocol_major,
			    dp->dp_protocol_minor));
			rdsv3_ib_set_flow_control(conn,
			    ntohl(dp->dp_credit));
		}
	}

	if (conn->c_version < RDS_PROTOCOL(3, 1)) {
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "RDS/IB: Connection to %u.%u.%u.%u version %u.%u failed",
		    NIPQUAD(conn->c_faddr),
		    RDS_PROTOCOL_MAJOR(conn->c_version),
		    RDS_PROTOCOL_MINOR(conn->c_version));
		rdsv3_conn_destroy(conn);
		return;
	} else {
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "RDS/IB: connected to %u.%u.%u.%u version %u.%u%s",
		    NIPQUAD(conn->c_faddr),
		    RDS_PROTOCOL_MAJOR(conn->c_version),
		    RDS_PROTOCOL_MINOR(conn->c_version),
		    ic->i_flowctl ? ", flow control" : "");
	}

	ASSERT(ic->i_soft_cq == NULL);
	ic->i_soft_cq = rdsv3_af_intr_thr_create(rdsv3_ib_tasklet_fn,
	    (void *)ic, SCQ_INTR_BIND_CPU, rds_ibdev->aft_hcagp,
	    ic->i_cq->ibt_cq);
	if (rdsv3_enable_snd_cq) {
		ic->i_snd_soft_cq = rdsv3_af_intr_thr_create(
		    rdsv3_ib_snd_tasklet_fn,
		    (void *)ic, SCQ_INTR_BIND_CPU, rds_ibdev->aft_hcagp,
		    ic->i_snd_cq->ibt_cq);
	}
	/* rdsv3_ib_refill_fn is expecting i_max_recv_alloc set */
	ic->i_max_recv_alloc = rdsv3_ib_sysctl_max_recv_allocation;
	ic->i_refill_rq = rdsv3_af_thr_create(rdsv3_ib_refill_fn, (void *)conn,
	    SCQ_WRK_BIND_CPU, rds_ibdev->aft_hcagp);
	rdsv3_af_grp_draw(rds_ibdev->aft_hcagp);

	(void) ib_req_notify_cq(ic->i_cq, IB_CQ_SOLICITED);
	if (rdsv3_enable_snd_cq) {
		(void) ib_req_notify_cq(ic->i_snd_cq, IB_CQ_NEXT_COMP);
	}

	/*
	 * Init rings and fill recv. this needs to wait until protocol
	 * negotiation
	 * is complete, since ring layout is different from 3.0 to 3.1.
	 */
	rdsv3_ib_send_init_ring(ic);
	rdsv3_ib_recv_init_ring(ic);
	/*
	 * Post receive buffers - as a side effect, this will update
	 * the posted credit count.
	 */
	(void) rdsv3_ib_recv_refill(conn, 1);

	/* Tune RNR behavior */
	rdsv3_ib_tune_rnr(ic, &qp_attr);

	qp_attr.qp_state = IB_QPS_RTS;
	err = ib_modify_qp(ic->i_cm_id->qp, &qp_attr, IB_QP_STATE);
	if (err)
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "ib_modify_qp(IB_QP_STATE, RTS): err=%d", err);

	/* update ib_device with this local ipaddr & conn */
	err = rdsv3_ib_update_ipaddr(rds_ibdev, conn->c_laddr);
	if (err)
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "rdsv3_ib_update_ipaddr failed (%d)", err);
	rdsv3_ib_add_conn(rds_ibdev, conn);

	/*
	 * If the peer gave us the last packet it saw, process this as if
	 * we had received a regular ACK.
	 */
	if (dp && dp->dp_ack_seq)
		rdsv3_send_drop_acked(conn, ntohll(dp->dp_ack_seq), NULL);

	rdsv3_connect_complete(conn);

	RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
	    "Return conn: %p event: %p",
	    conn, event);
}