netlink: fix for too early rmmod
[safe/jmp/linux-2.6] / net / rds / ib_cm.c
index 1eb0c29..647cb8f 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_laddr,
+                       &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);
 
@@ -193,9 +203,9 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data)
                rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST);
                break;
        default:
-               printk(KERN_WARNING "RDS/ib: unhandled QP event %u "
-                      "on connection to %pI4\n", event->event,
-                      &conn->c_faddr);
+               rds_ib_conn_error(conn, "RDS/IB: Fatal QP Event %u "
+                       "- connection %pI4->%pI4, reconnecting\n",
+                       event->event, &conn->c_laddr, &conn->c_faddr);
                break;
        }
 }
@@ -324,7 +334,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
                rdsdebug("send allocation failed\n");
                goto out;
        }
-       rds_ib_send_init_ring(ic);
+       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) {
@@ -332,14 +342,10 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
                rdsdebug("recv allocation failed\n");
                goto out;
        }
+       memset(ic->i_recvs, 0, ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
 
-       rds_ib_recv_init_ring(ic);
        rds_ib_recv_init_ack(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);
-
        rdsdebug("conn %p pd %p mr %p cq %p %p\n", conn, ic->i_pd, ic->i_mr,
                 ic->i_send_cq, ic->i_recv_cq);
 
@@ -371,8 +377,8 @@ static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event)
        }
 
        /* Even if len is crap *now* I still want to check it. -ASG */
-       if (event->param.conn.private_data_len < sizeof (*dp)
-           || dp->dp_protocol_major == 0)
+       if (event->param.conn.private_data_len < sizeof (*dp) ||
+           dp->dp_protocol_major == 0)
                return RDS_PROTOCOL_3_0;
 
        common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS;
@@ -688,6 +694,8 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
                return -ENOMEM;
 
        INIT_LIST_HEAD(&ic->ib_node);
+       tasklet_init(&ic->i_recv_tasklet, rds_ib_recv_tasklet_fn,
+                    (unsigned long) ic);
        mutex_init(&ic->i_recv_mutex);
 #ifndef KERNEL_HAS_ATOMIC64
        spin_lock_init(&ic->i_ack_lock);