]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/rds/ib_recv.c
ARM: Merge for-2637/s3c24xx/h1940
[karo-tx-linux.git] / net / rds / ib_recv.c
index 1add097fe198726420dd298278d5d8d37040ea7f..e29e0ca32f740d978aeccf23a4fba5453a4e8aa4 100644 (file)
@@ -282,6 +282,7 @@ static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic
                if (!frag)
                        return NULL;
 
+               sg_init_table(&frag->f_sg, 1);
                ret = rds_page_remainder_alloc(&frag->f_sg,
                                               RDS_FRAG_SIZE, page_mask);
                if (ret) {
@@ -353,7 +354,7 @@ out:
  *
  * -1 is returned if posting fails due to temporary resource exhaustion.
  */
-int rds_ib_recv_refill(struct rds_connection *conn, int prefill)
+void rds_ib_recv_refill(struct rds_connection *conn, int prefill)
 {
        struct rds_ib_connection *ic = conn->c_transport_data;
        struct rds_ib_recv_work *recv;
@@ -367,14 +368,12 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill)
                if (pos >= ic->i_recv_ring.w_nr) {
                        printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n",
                                        pos);
-                       ret = -EINVAL;
                        break;
                }
 
                recv = &ic->i_recvs[pos];
                ret = rds_ib_recv_refill_one(conn, recv, prefill);
                if (ret) {
-                       ret = -1;
                        break;
                }
 
@@ -388,7 +387,6 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill)
                               "%pI4 returned %d, disconnecting and "
                               "reconnecting\n", &conn->c_faddr,
                               ret);
-                       ret = -1;
                        break;
                }
 
@@ -401,7 +399,6 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill)
 
        if (ret)
                rds_ib_ring_unalloc(&ic->i_recv_ring, 1);
-       return ret;
 }
 
 /*
@@ -969,8 +966,9 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic,
        struct rds_ib_recv_work *recv;
 
        while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) {
-               rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n",
-                        (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
+               rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n",
+                        (unsigned long long)wc.wr_id, wc.status,
+                        rds_ib_wc_status_str(wc.status), wc.byte_len,
                         be32_to_cpu(wc.ex.imm_data));
                rds_ib_stats_inc(s_ib_rx_cq_event);
 
@@ -983,18 +981,23 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic,
                 * to get a recv completion _before_ the rdmacm ESTABLISHED
                 * event is processed.
                 */
-               if (rds_conn_up(conn) || rds_conn_connecting(conn)) {
+               if (wc.status == IB_WC_SUCCESS) {
+                       rds_ib_process_recv(conn, recv, wc.byte_len, state);
+               } else {
                        /* We expect errors as the qp is drained during shutdown */
-                       if (wc.status == IB_WC_SUCCESS) {
-                               rds_ib_process_recv(conn, recv, wc.byte_len, state);
-                       } else {
-                               rds_ib_conn_error(conn, "recv completion on "
-                                      "%pI4 had status %u, disconnecting and "
-                                      "reconnecting\n", &conn->c_faddr,
-                                      wc.status);
-                       }
+                       if (rds_conn_up(conn) || rds_conn_connecting(conn))
+                               rds_ib_conn_error(conn, "recv completion on %pI4 had "
+                                                 "status %u (%s), disconnecting and "
+                                                 "reconnecting\n", &conn->c_faddr,
+                                                 wc.status,
+                                                 rds_ib_wc_status_str(wc.status));
                }
 
+               /*
+                * It's very important that we only free this ring entry if we've truly
+                * freed the resources allocated to the entry.  The refilling path can
+                * leak if we don't.
+                */
                rds_ib_ring_free(&ic->i_recv_ring, 1);
        }
 }
@@ -1040,7 +1043,7 @@ int rds_ib_recv(struct rds_connection *conn)
        return ret;
 }
 
-int __init rds_ib_recv_init(void)
+int rds_ib_recv_init(void)
 {
        struct sysinfo si;
        int ret = -ENOMEM;
@@ -1051,13 +1054,13 @@ int __init rds_ib_recv_init(void)
 
        rds_ib_incoming_slab = kmem_cache_create("rds_ib_incoming",
                                        sizeof(struct rds_ib_incoming),
-                                       0, 0, NULL);
+                                       0, SLAB_HWCACHE_ALIGN, NULL);
        if (!rds_ib_incoming_slab)
                goto out;
 
        rds_ib_frag_slab = kmem_cache_create("rds_ib_frag",
                                        sizeof(struct rds_page_frag),
-                                       0, 0, NULL);
+                                       0, SLAB_HWCACHE_ALIGN, NULL);
        if (!rds_ib_frag_slab)
                kmem_cache_destroy(rds_ib_incoming_slab);
        else