]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/rds/ib_cm.c
RDS: Refill recv ring directly from tasklet
[net-next-2.6.git] / net / rds / ib_cm.c
index f68832798db224d6abffcc08f4ad494fa2b3bc17..75eda9c82135fea944b394d27090ae88ca92face 100644 (file)
@@ -111,11 +111,21 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
                }
        }
 
-       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" : "");
+       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
@@ -125,7 +135,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
        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);
+       rds_ib_recv_refill(conn, 1);
 
        /* Tune RNR behavior */
        rds_ib_tune_rnr(ic, &qp_attr);
@@ -153,18 +163,25 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
 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 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;
+
        memset(conn_param, 0, sizeof(struct rdma_conn_param));
-       /* XXX tune these? */
-       conn_param->responder_resources = 1;
-       conn_param->initiator_depth = 1;
+
+       rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client);
+
+       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) {
-               struct rds_ib_connection *ic = conn->c_transport_data;
-
                memset(dp, 0, sizeof(*dp));
                dp->dp_saddr = conn->c_laddr;
                dp->dp_daddr = conn->c_faddr;
@@ -230,7 +247,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
         * the rds_ibdev at all.
         */
        rds_ibdev = ib_get_client_data(dev, &rds_ib_client);
-       if (rds_ibdev == NULL) {
+       if (!rds_ibdev) {
                if (printk_ratelimit())
                        printk(KERN_NOTICE "RDS/IB: No client_data for device %s\n",
                                        dev->name);
@@ -306,7 +323,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
                                           ic->i_send_ring.w_nr *
                                                sizeof(struct rds_header),
                                           &ic->i_send_hdrs_dma, GFP_KERNEL);
-       if (ic->i_send_hdrs == NULL) {
+       if (!ic->i_send_hdrs) {
                ret = -ENOMEM;
                rdsdebug("ib_dma_alloc_coherent send failed\n");
                goto out;
@@ -316,7 +333,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
                                           ic->i_recv_ring.w_nr *
                                                sizeof(struct rds_header),
                                           &ic->i_recv_hdrs_dma, GFP_KERNEL);
-       if (ic->i_recv_hdrs == NULL) {
+       if (!ic->i_recv_hdrs) {
                ret = -ENOMEM;
                rdsdebug("ib_dma_alloc_coherent recv failed\n");
                goto out;
@@ -324,14 +341,14 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
 
        ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header),
                                       &ic->i_ack_dma, GFP_KERNEL);
-       if (ic->i_ack == NULL) {
+       if (!ic->i_ack) {
                ret = -ENOMEM;
                rdsdebug("ib_dma_alloc_coherent ack failed\n");
                goto out;
        }
 
        ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work));
-       if (ic->i_sends == NULL) {
+       if (!ic->i_sends) {
                ret = -ENOMEM;
                rdsdebug("send allocation failed\n");
                goto out;
@@ -339,7 +356,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
        memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work));
 
        ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
-       if (ic->i_recvs == NULL) {
+       if (!ic->i_recvs) {
                ret = -ENOMEM;
                rdsdebug("recv allocation failed\n");
                goto out;
@@ -479,7 +496,9 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
                goto out;
        }
 
-       rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version);
+       rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version,
+               event->param.conn.responder_resources,
+               event->param.conn.initiator_depth);
 
        /* rdma_accept() calls rdma_reject() internally if it fails */
        err = rdma_accept(cm_id, &conn_param);
@@ -516,8 +535,8 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id)
                goto out;
        }
 
-       rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION);
-
+       rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION,
+               UINT_MAX, UINT_MAX);
        ret = rdma_connect(cm_id, &conn_param);
        if (ret)
                rds_ib_conn_error(conn, "rdma_connect failed (%d)\n", ret);
@@ -601,8 +620,11 @@ void rds_ib_conn_shutdown(struct rds_connection *conn)
                                ic->i_cm_id, err);
                }
 
+               /*
+                * Don't wait for the send ring to be empty -- there may be completed
+                * non-signaled entries sitting on there. We unmap these below.
+                */
                wait_event(rds_ib_ring_empty_wait,
-                       rds_ib_ring_empty(&ic->i_send_ring) &&
                        rds_ib_ring_empty(&ic->i_recv_ring));
 
                if (ic->i_send_hdrs)
@@ -654,9 +676,12 @@ void rds_ib_conn_shutdown(struct rds_connection *conn)
        BUG_ON(ic->rds_ibdev);
 
        /* Clear pending transmit */
-       if (ic->i_rm) {
-               rds_message_put(ic->i_rm);
-               ic->i_rm = NULL;
+       if (ic->i_data_op) {
+               struct rds_message *rm;
+
+               rm = container_of(ic->i_data_op, struct rds_message, data);
+               rds_message_put(rm);
+               ic->i_data_op = NULL;
        }
 
        /* Clear the ACK state */
@@ -693,7 +718,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 
        /* XXX too lazy? */
        ic = kzalloc(sizeof(struct rds_ib_connection), GFP_KERNEL);
-       if (ic == NULL)
+       if (!ic)
                return -ENOMEM;
 
        INIT_LIST_HEAD(&ic->ib_node);