aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/af_rds.c12
-rw-r--r--net/rds/cong.c3
-rw-r--r--net/rds/connection.c1
-rw-r--r--net/rds/ib.c1
-rw-r--r--net/rds/ib_cm.c5
-rw-r--r--net/rds/ib_rdma.c6
-rw-r--r--net/rds/ib_recv.c5
-rw-r--r--net/rds/ib_send.c20
-rw-r--r--net/rds/info.c1
-rw-r--r--net/rds/iw.c1
-rw-r--r--net/rds/iw_cm.c6
-rw-r--r--net/rds/iw_rdma.c1
-rw-r--r--net/rds/iw_recv.c5
-rw-r--r--net/rds/iw_send.c3
-rw-r--r--net/rds/loop.c8
-rw-r--r--net/rds/message.c1
-rw-r--r--net/rds/page.c28
-rw-r--r--net/rds/rdma.c5
-rw-r--r--net/rds/rdma_transport.c7
-rw-r--r--net/rds/rds.h4
-rw-r--r--net/rds/recv.c5
-rw-r--r--net/rds/send.c41
-rw-r--r--net/rds/tcp.c1
-rw-r--r--net/rds/tcp_connect.c13
-rw-r--r--net/rds/tcp_listen.c11
-rw-r--r--net/rds/tcp_recv.c6
-rw-r--r--net/rds/tcp_send.c12
-rw-r--r--net/rds/threads.c2
28 files changed, 120 insertions, 94 deletions
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 853c52be781f..aebfecbdb841 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/gfp.h>
36#include <linux/in.h> 37#include <linux/in.h>
37#include <linux/poll.h> 38#include <linux/poll.h>
38#include <net/sock.h> 39#include <net/sock.h>
@@ -157,9 +158,10 @@ static unsigned int rds_poll(struct file *file, struct socket *sock,
157 unsigned int mask = 0; 158 unsigned int mask = 0;
158 unsigned long flags; 159 unsigned long flags;
159 160
160 poll_wait(file, sk->sk_sleep, wait); 161 poll_wait(file, sk_sleep(sk), wait);
161 162
162 poll_wait(file, &rds_poll_waitq, wait); 163 if (rs->rs_seen_congestion)
164 poll_wait(file, &rds_poll_waitq, wait);
163 165
164 read_lock_irqsave(&rs->rs_recv_lock, flags); 166 read_lock_irqsave(&rs->rs_recv_lock, flags);
165 if (!rs->rs_cong_monitor) { 167 if (!rs->rs_cong_monitor) {
@@ -181,6 +183,10 @@ static unsigned int rds_poll(struct file *file, struct socket *sock,
181 mask |= (POLLOUT | POLLWRNORM); 183 mask |= (POLLOUT | POLLWRNORM);
182 read_unlock_irqrestore(&rs->rs_recv_lock, flags); 184 read_unlock_irqrestore(&rs->rs_recv_lock, flags);
183 185
186 /* clear state any time we wake a seen-congested socket */
187 if (mask)
188 rs->rs_seen_congestion = 0;
189
184 return mask; 190 return mask;
185} 191}
186 192
@@ -446,7 +452,6 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
446 struct rds_info_lengths *lens) 452 struct rds_info_lengths *lens)
447{ 453{
448 struct rds_sock *rs; 454 struct rds_sock *rs;
449 struct sock *sk;
450 struct rds_incoming *inc; 455 struct rds_incoming *inc;
451 unsigned long flags; 456 unsigned long flags;
452 unsigned int total = 0; 457 unsigned int total = 0;
@@ -456,7 +461,6 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
456 spin_lock_irqsave(&rds_sock_lock, flags); 461 spin_lock_irqsave(&rds_sock_lock, flags);
457 462
458 list_for_each_entry(rs, &rds_sock_list, rs_item) { 463 list_for_each_entry(rs, &rds_sock_list, rs_item) {
459 sk = rds_rs_to_sk(rs);
460 read_lock(&rs->rs_recv_lock); 464 read_lock(&rs->rs_recv_lock);
461 465
462 /* XXX too lazy to maintain counts.. */ 466 /* XXX too lazy to maintain counts.. */
diff --git a/net/rds/cong.c b/net/rds/cong.c
index 6d06cac2649c..0871a29f0780 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -30,6 +30,7 @@
30 * SOFTWARE. 30 * SOFTWARE.
31 * 31 *
32 */ 32 */
33#include <linux/slab.h>
33#include <linux/types.h> 34#include <linux/types.h>
34#include <linux/rbtree.h> 35#include <linux/rbtree.h>
35 36
@@ -218,8 +219,6 @@ void rds_cong_queue_updates(struct rds_cong_map *map)
218 spin_lock_irqsave(&rds_cong_lock, flags); 219 spin_lock_irqsave(&rds_cong_lock, flags);
219 220
220 list_for_each_entry(conn, &map->m_conn_list, c_map_item) { 221 list_for_each_entry(conn, &map->m_conn_list, c_map_item) {
221 if (conn->c_loopback)
222 continue;
223 if (!test_and_set_bit(0, &conn->c_map_queued)) { 222 if (!test_and_set_bit(0, &conn->c_map_queued)) {
224 rds_stats_inc(s_cong_update_queued); 223 rds_stats_inc(s_cong_update_queued);
225 queue_delayed_work(rds_wq, &conn->c_send_w, 0); 224 queue_delayed_work(rds_wq, &conn->c_send_w, 0);
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 278f607ab603..7619b671ca28 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -32,6 +32,7 @@
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/list.h> 34#include <linux/list.h>
35#include <linux/slab.h>
35#include <net/inet_hashtables.h> 36#include <net/inet_hashtables.h>
36 37
37#include "rds.h" 38#include "rds.h"
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 3b8992361042..8f2d6dd7700a 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -37,6 +37,7 @@
37#include <linux/inetdevice.h> 37#include <linux/inetdevice.h>
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/slab.h>
40 41
41#include "rds.h" 42#include "rds.h"
42#include "ib.h" 43#include "ib.h"
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 647cb8ffc39b..f68832798db2 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -32,6 +32,7 @@
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/in.h> 34#include <linux/in.h>
35#include <linux/slab.h>
35#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
36 37
37#include "rds.h" 38#include "rds.h"
@@ -203,9 +204,10 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data)
203 rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST); 204 rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST);
204 break; 205 break;
205 default: 206 default:
206 rds_ib_conn_error(conn, "RDS/IB: Fatal QP Event %u " 207 rdsdebug("Fatal QP Event %u "
207 "- connection %pI4->%pI4, reconnecting\n", 208 "- connection %pI4->%pI4, reconnecting\n",
208 event->event, &conn->c_laddr, &conn->c_faddr); 209 event->event, &conn->c_laddr, &conn->c_faddr);
210 rds_conn_drop(conn);
209 break; 211 break;
210 } 212 }
211} 213}
@@ -473,6 +475,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
473 err = rds_ib_setup_qp(conn); 475 err = rds_ib_setup_qp(conn);
474 if (err) { 476 if (err) {
475 rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err); 477 rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err);
478 mutex_unlock(&conn->c_cm_lock);
476 goto out; 479 goto out;
477 } 480 }
478 481
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 4b0da865a72c..a54cd63f9e35 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34 35
35#include "rds.h" 36#include "rds.h"
36#include "rdma.h" 37#include "rdma.h"
@@ -234,8 +235,8 @@ void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool)
234{ 235{
235 flush_workqueue(rds_wq); 236 flush_workqueue(rds_wq);
236 rds_ib_flush_mr_pool(pool, 1); 237 rds_ib_flush_mr_pool(pool, 1);
237 BUG_ON(atomic_read(&pool->item_count)); 238 WARN_ON(atomic_read(&pool->item_count));
238 BUG_ON(atomic_read(&pool->free_pinned)); 239 WARN_ON(atomic_read(&pool->free_pinned));
239 kfree(pool); 240 kfree(pool);
240} 241}
241 242
@@ -440,6 +441,7 @@ static void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr)
440 441
441 /* FIXME we need a way to tell a r/w MR 442 /* FIXME we need a way to tell a r/w MR
442 * from a r/o MR */ 443 * from a r/o MR */
444 BUG_ON(in_interrupt());
443 set_page_dirty(page); 445 set_page_dirty(page);
444 put_page(page); 446 put_page(page);
445 } 447 }
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 04dc0d3f3c95..c74e9904a6b2 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34#include <linux/pci.h> 35#include <linux/pci.h>
35#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
36#include <rdma/rdma_cm.h> 37#include <rdma/rdma_cm.h>
@@ -468,8 +469,8 @@ static void rds_ib_send_ack(struct rds_ib_connection *ic, unsigned int adv_credi
468 set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); 469 set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags);
469 470
470 rds_ib_stats_inc(s_ib_ack_send_failure); 471 rds_ib_stats_inc(s_ib_ack_send_failure);
471 /* Need to finesse this later. */ 472
472 BUG(); 473 rds_ib_conn_error(ic->conn, "sending ack failed\n");
473 } else 474 } else
474 rds_ib_stats_inc(s_ib_ack_sent); 475 rds_ib_stats_inc(s_ib_ack_sent);
475} 476}
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index a10fab6886d1..17fa80803ab0 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -243,8 +243,12 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
243 struct rds_message *rm; 243 struct rds_message *rm;
244 244
245 rm = rds_send_get_message(conn, send->s_op); 245 rm = rds_send_get_message(conn, send->s_op);
246 if (rm) 246 if (rm) {
247 if (rm->m_rdma_op)
248 rds_ib_send_unmap_rdma(ic, rm->m_rdma_op);
247 rds_ib_send_rdma_complete(rm, wc.status); 249 rds_ib_send_rdma_complete(rm, wc.status);
250 rds_message_put(rm);
251 }
248 } 252 }
249 253
250 oldest = (oldest + 1) % ic->i_send_ring.w_nr; 254 oldest = (oldest + 1) % ic->i_send_ring.w_nr;
@@ -482,6 +486,13 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
482 BUG_ON(off % RDS_FRAG_SIZE); 486 BUG_ON(off % RDS_FRAG_SIZE);
483 BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header)); 487 BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header));
484 488
489 /* Do not send cong updates to IB loopback */
490 if (conn->c_loopback
491 && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
492 rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
493 return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
494 }
495
485 /* FIXME we may overallocate here */ 496 /* FIXME we may overallocate here */
486 if (be32_to_cpu(rm->m_inc.i_hdr.h_len) == 0) 497 if (be32_to_cpu(rm->m_inc.i_hdr.h_len) == 0)
487 i = 1; 498 i = 1;
@@ -574,8 +585,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
574 rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); 585 rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
575 adv_credits += posted; 586 adv_credits += posted;
576 BUG_ON(adv_credits > 255); 587 BUG_ON(adv_credits > 255);
577 } else if (ic->i_rm != rm) 588 }
578 BUG();
579 589
580 send = &ic->i_sends[pos]; 590 send = &ic->i_sends[pos];
581 first = send; 591 first = send;
@@ -714,8 +724,8 @@ add_header:
714 ic->i_rm = prev->s_rm; 724 ic->i_rm = prev->s_rm;
715 prev->s_rm = NULL; 725 prev->s_rm = NULL;
716 } 726 }
717 /* Finesse this later */ 727
718 BUG(); 728 rds_ib_conn_error(ic->conn, "ib_post_send failed\n");
719 goto out; 729 goto out;
720 } 730 }
721 731
diff --git a/net/rds/info.c b/net/rds/info.c
index 814a91a6f4a7..c45c4173a44d 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -32,6 +32,7 @@
32 */ 32 */
33#include <linux/percpu.h> 33#include <linux/percpu.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/slab.h>
35#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
36 37
37#include "rds.h" 38#include "rds.h"
diff --git a/net/rds/iw.c b/net/rds/iw.c
index b28fa8525b24..c8f3d3525cb9 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -37,6 +37,7 @@
37#include <linux/inetdevice.h> 37#include <linux/inetdevice.h>
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/slab.h>
40 41
41#include "rds.h" 42#include "rds.h"
42#include "iw.h" 43#include "iw.h"
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index 394cf6b4d0aa..b5dd6ac39be8 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -32,6 +32,7 @@
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/in.h> 34#include <linux/in.h>
35#include <linux/slab.h>
35#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
36 37
37#include "rds.h" 38#include "rds.h"
@@ -156,9 +157,11 @@ static void rds_iw_qp_event_handler(struct ib_event *event, void *data)
156 case IB_EVENT_QP_REQ_ERR: 157 case IB_EVENT_QP_REQ_ERR:
157 case IB_EVENT_QP_FATAL: 158 case IB_EVENT_QP_FATAL:
158 default: 159 default:
159 rds_iw_conn_error(conn, "RDS/IW: Fatal QP Event %u - connection %pI4->%pI4...reconnecting\n", 160 rdsdebug("Fatal QP Event %u "
161 "- connection %pI4->%pI4, reconnecting\n",
160 event->event, &conn->c_laddr, 162 event->event, &conn->c_laddr,
161 &conn->c_faddr); 163 &conn->c_faddr);
164 rds_conn_drop(conn);
162 break; 165 break;
163 } 166 }
164} 167}
@@ -449,6 +452,7 @@ int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id,
449 err = rds_iw_setup_qp(conn); 452 err = rds_iw_setup_qp(conn);
450 if (err) { 453 if (err) {
451 rds_iw_conn_error(conn, "rds_iw_setup_qp failed (%d)\n", err); 454 rds_iw_conn_error(conn, "rds_iw_setup_qp failed (%d)\n", err);
455 mutex_unlock(&conn->c_cm_lock);
452 goto out; 456 goto out;
453 } 457 }
454 458
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c
index 9eda11cca956..13dc1862d862 100644
--- a/net/rds/iw_rdma.c
+++ b/net/rds/iw_rdma.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34 35
35#include "rds.h" 36#include "rds.h"
36#include "rdma.h" 37#include "rdma.h"
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 54af7d6b92da..3d479067d54d 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34#include <linux/pci.h> 35#include <linux/pci.h>
35#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
36#include <rdma/rdma_cm.h> 37#include <rdma/rdma_cm.h>
@@ -468,8 +469,8 @@ static void rds_iw_send_ack(struct rds_iw_connection *ic, unsigned int adv_credi
468 set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); 469 set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags);
469 470
470 rds_iw_stats_inc(s_iw_ack_send_failure); 471 rds_iw_stats_inc(s_iw_ack_send_failure);
471 /* Need to finesse this later. */ 472
472 BUG(); 473 rds_iw_conn_error(ic->conn, "sending ack failed\n");
473 } else 474 } else
474 rds_iw_stats_inc(s_iw_ack_sent); 475 rds_iw_stats_inc(s_iw_ack_sent);
475} 476}
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c
index 1379e9d66a78..52182ff7519e 100644
--- a/net/rds/iw_send.c
+++ b/net/rds/iw_send.c
@@ -616,8 +616,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
616 rds_iw_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); 616 rds_iw_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
617 adv_credits += posted; 617 adv_credits += posted;
618 BUG_ON(adv_credits > 255); 618 BUG_ON(adv_credits > 255);
619 } else if (ic->i_rm != rm) 619 }
620 BUG();
621 620
622 send = &ic->i_sends[pos]; 621 send = &ic->i_sends[pos];
623 first = send; 622 first = send;
diff --git a/net/rds/loop.c b/net/rds/loop.c
index 4a61997f554d..dd9879379457 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34#include <linux/in.h> 35#include <linux/in.h>
35 36
36#include "rds.h" 37#include "rds.h"
@@ -80,16 +81,9 @@ static int rds_loop_xmit_cong_map(struct rds_connection *conn,
80 struct rds_cong_map *map, 81 struct rds_cong_map *map,
81 unsigned long offset) 82 unsigned long offset)
82{ 83{
83 unsigned long i;
84
85 BUG_ON(offset); 84 BUG_ON(offset);
86 BUG_ON(map != conn->c_lcong); 85 BUG_ON(map != conn->c_lcong);
87 86
88 for (i = 0; i < RDS_CONG_MAP_PAGES; i++) {
89 memcpy((void *)conn->c_fcong->m_page_addrs[i],
90 (void *)map->m_page_addrs[i], PAGE_SIZE);
91 }
92
93 rds_cong_map_updated(conn->c_fcong, ~(u64) 0); 87 rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
94 88
95 return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; 89 return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
diff --git a/net/rds/message.c b/net/rds/message.c
index 73e600ffd87f..9a1d67e001ba 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34 35
35#include "rds.h" 36#include "rds.h"
36#include "rdma.h" 37#include "rdma.h"
diff --git a/net/rds/page.c b/net/rds/page.c
index 36790122dfd4..1dfbfea12e9b 100644
--- a/net/rds/page.c
+++ b/net/rds/page.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/highmem.h> 33#include <linux/highmem.h>
34#include <linux/gfp.h>
34 35
35#include "rds.h" 36#include "rds.h"
36 37
@@ -56,30 +57,17 @@ int rds_page_copy_user(struct page *page, unsigned long offset,
56 unsigned long ret; 57 unsigned long ret;
57 void *addr; 58 void *addr;
58 59
59 if (to_user) 60 addr = kmap(page);
61 if (to_user) {
60 rds_stats_add(s_copy_to_user, bytes); 62 rds_stats_add(s_copy_to_user, bytes);
61 else 63 ret = copy_to_user(ptr, addr + offset, bytes);
64 } else {
62 rds_stats_add(s_copy_from_user, bytes); 65 rds_stats_add(s_copy_from_user, bytes);
63 66 ret = copy_from_user(addr + offset, ptr, bytes);
64 addr = kmap_atomic(page, KM_USER0);
65 if (to_user)
66 ret = __copy_to_user_inatomic(ptr, addr + offset, bytes);
67 else
68 ret = __copy_from_user_inatomic(addr + offset, ptr, bytes);
69 kunmap_atomic(addr, KM_USER0);
70
71 if (ret) {
72 addr = kmap(page);
73 if (to_user)
74 ret = copy_to_user(ptr, addr + offset, bytes);
75 else
76 ret = copy_from_user(addr + offset, ptr, bytes);
77 kunmap(page);
78 if (ret)
79 return -EFAULT;
80 } 67 }
68 kunmap(page);
81 69
82 return 0; 70 return ret ? -EFAULT : 0;
83} 71}
84EXPORT_SYMBOL_GPL(rds_page_copy_user); 72EXPORT_SYMBOL_GPL(rds_page_copy_user);
85 73
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 4c64daa1f5d5..75fd13bb631b 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/pagemap.h> 33#include <linux/pagemap.h>
34#include <linux/slab.h>
34#include <linux/rbtree.h> 35#include <linux/rbtree.h>
35#include <linux/dma-mapping.h> /* for DMA_*_DEVICE */ 36#include <linux/dma-mapping.h> /* for DMA_*_DEVICE */
36 37
@@ -438,8 +439,10 @@ void rds_rdma_free_op(struct rds_rdma_op *ro)
438 /* Mark page dirty if it was possibly modified, which 439 /* Mark page dirty if it was possibly modified, which
439 * is the case for a RDMA_READ which copies from remote 440 * is the case for a RDMA_READ which copies from remote
440 * to local memory */ 441 * to local memory */
441 if (!ro->r_write) 442 if (!ro->r_write) {
443 BUG_ON(in_interrupt());
442 set_page_dirty(page); 444 set_page_dirty(page);
445 }
443 put_page(page); 446 put_page(page);
444 } 447 }
445 448
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 9ece910ea394..e599ba2f950d 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -101,7 +101,7 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
101 break; 101 break;
102 102
103 case RDMA_CM_EVENT_DISCONNECTED: 103 case RDMA_CM_EVENT_DISCONNECTED:
104 printk(KERN_WARNING "RDS/RDMA: DISCONNECT event - dropping connection " 104 rdsdebug("DISCONNECT event - dropping connection "
105 "%pI4->%pI4\n", &conn->c_laddr, 105 "%pI4->%pI4\n", &conn->c_laddr,
106 &conn->c_faddr); 106 &conn->c_faddr);
107 rds_conn_drop(conn); 107 rds_conn_drop(conn);
@@ -109,8 +109,7 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
109 109
110 default: 110 default:
111 /* things like device disconnect? */ 111 /* things like device disconnect? */
112 printk(KERN_ERR "unknown event %u\n", event->event); 112 printk(KERN_ERR "RDS: unknown event %u!\n", event->event);
113 BUG();
114 break; 113 break;
115 } 114 }
116 115
@@ -134,7 +133,7 @@ static int __init rds_rdma_listen_init(void)
134 ret = PTR_ERR(cm_id); 133 ret = PTR_ERR(cm_id);
135 printk(KERN_ERR "RDS/RDMA: failed to setup listener, " 134 printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
136 "rdma_create_id() returned %d\n", ret); 135 "rdma_create_id() returned %d\n", ret);
137 goto out; 136 return ret;
138 } 137 }
139 138
140 sin.sin_family = AF_INET, 139 sin.sin_family = AF_INET,
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 85d6f897ecc7..c224b5bb3ba9 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -388,6 +388,8 @@ struct rds_sock {
388 388
389 /* flag indicating we were congested or not */ 389 /* flag indicating we were congested or not */
390 int rs_congested; 390 int rs_congested;
391 /* seen congestion (ENOBUFS) when sending? */
392 int rs_seen_congestion;
391 393
392 /* rs_lock protects all these adjacent members before the newline */ 394 /* rs_lock protects all these adjacent members before the newline */
393 spinlock_t rs_lock; 395 spinlock_t rs_lock;
@@ -490,7 +492,7 @@ void rds_sock_put(struct rds_sock *rs);
490void rds_wake_sk_sleep(struct rds_sock *rs); 492void rds_wake_sk_sleep(struct rds_sock *rs);
491static inline void __rds_wake_sk_sleep(struct sock *sk) 493static inline void __rds_wake_sk_sleep(struct sock *sk)
492{ 494{
493 wait_queue_head_t *waitq = sk->sk_sleep; 495 wait_queue_head_t *waitq = sk_sleep(sk);
494 496
495 if (!sock_flag(sk, SOCK_DEAD) && waitq) 497 if (!sock_flag(sk, SOCK_DEAD) && waitq)
496 wake_up(waitq); 498 wake_up(waitq);
diff --git a/net/rds/recv.c b/net/rds/recv.c
index b426d67f760c..c93588c2d553 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34#include <net/sock.h> 35#include <net/sock.h>
35#include <linux/in.h> 36#include <linux/in.h>
36 37
@@ -296,7 +297,7 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc,
296int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr) 297int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr)
297{ 298{
298 struct rds_notifier *notifier; 299 struct rds_notifier *notifier;
299 struct rds_rdma_notify cmsg; 300 struct rds_rdma_notify cmsg = { 0 }; /* fill holes with zero */
300 unsigned int count = 0, max_messages = ~0U; 301 unsigned int count = 0, max_messages = ~0U;
301 unsigned long flags; 302 unsigned long flags;
302 LIST_HEAD(copy); 303 LIST_HEAD(copy);
@@ -431,7 +432,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
431 break; 432 break;
432 } 433 }
433 434
434 timeo = wait_event_interruptible_timeout(*sk->sk_sleep, 435 timeo = wait_event_interruptible_timeout(*sk_sleep(sk),
435 (!list_empty(&rs->rs_notify_queue) || 436 (!list_empty(&rs->rs_notify_queue) ||
436 rs->rs_cong_notify || 437 rs->rs_cong_notify ||
437 rds_next_incoming(rs, &inc)), timeo); 438 rds_next_incoming(rs, &inc)), timeo);
diff --git a/net/rds/send.c b/net/rds/send.c
index b2fccfc20769..9c1c6bcaa6c9 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/gfp.h>
34#include <net/sock.h> 35#include <net/sock.h>
35#include <linux/in.h> 36#include <linux/in.h>
36#include <linux/list.h> 37#include <linux/list.h>
@@ -507,12 +508,13 @@ EXPORT_SYMBOL_GPL(rds_send_get_message);
507 */ 508 */
508void rds_send_remove_from_sock(struct list_head *messages, int status) 509void rds_send_remove_from_sock(struct list_head *messages, int status)
509{ 510{
510 unsigned long flags = 0; /* silence gcc :P */ 511 unsigned long flags;
511 struct rds_sock *rs = NULL; 512 struct rds_sock *rs = NULL;
512 struct rds_message *rm; 513 struct rds_message *rm;
513 514
514 local_irq_save(flags);
515 while (!list_empty(messages)) { 515 while (!list_empty(messages)) {
516 int was_on_sock = 0;
517
516 rm = list_entry(messages->next, struct rds_message, 518 rm = list_entry(messages->next, struct rds_message,
517 m_conn_item); 519 m_conn_item);
518 list_del_init(&rm->m_conn_item); 520 list_del_init(&rm->m_conn_item);
@@ -527,20 +529,19 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
527 * while we're messing with it. It does not prevent the 529 * while we're messing with it. It does not prevent the
528 * message from being removed from the socket, though. 530 * message from being removed from the socket, though.
529 */ 531 */
530 spin_lock(&rm->m_rs_lock); 532 spin_lock_irqsave(&rm->m_rs_lock, flags);
531 if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) 533 if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags))
532 goto unlock_and_drop; 534 goto unlock_and_drop;
533 535
534 if (rs != rm->m_rs) { 536 if (rs != rm->m_rs) {
535 if (rs) { 537 if (rs) {
536 spin_unlock(&rs->rs_lock);
537 rds_wake_sk_sleep(rs); 538 rds_wake_sk_sleep(rs);
538 sock_put(rds_rs_to_sk(rs)); 539 sock_put(rds_rs_to_sk(rs));
539 } 540 }
540 rs = rm->m_rs; 541 rs = rm->m_rs;
541 spin_lock(&rs->rs_lock);
542 sock_hold(rds_rs_to_sk(rs)); 542 sock_hold(rds_rs_to_sk(rs));
543 } 543 }
544 spin_lock(&rs->rs_lock);
544 545
545 if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { 546 if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) {
546 struct rds_rdma_op *ro = rm->m_rdma_op; 547 struct rds_rdma_op *ro = rm->m_rdma_op;
@@ -557,21 +558,22 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
557 notifier->n_status = status; 558 notifier->n_status = status;
558 rm->m_rdma_op->r_notifier = NULL; 559 rm->m_rdma_op->r_notifier = NULL;
559 } 560 }
560 rds_message_put(rm); 561 was_on_sock = 1;
561 rm->m_rs = NULL; 562 rm->m_rs = NULL;
562 } 563 }
564 spin_unlock(&rs->rs_lock);
563 565
564unlock_and_drop: 566unlock_and_drop:
565 spin_unlock(&rm->m_rs_lock); 567 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
566 rds_message_put(rm); 568 rds_message_put(rm);
569 if (was_on_sock)
570 rds_message_put(rm);
567 } 571 }
568 572
569 if (rs) { 573 if (rs) {
570 spin_unlock(&rs->rs_lock);
571 rds_wake_sk_sleep(rs); 574 rds_wake_sk_sleep(rs);
572 sock_put(rds_rs_to_sk(rs)); 575 sock_put(rds_rs_to_sk(rs));
573 } 576 }
574 local_irq_restore(flags);
575} 577}
576 578
577/* 579/*
@@ -633,9 +635,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
633 list_move(&rm->m_sock_item, &list); 635 list_move(&rm->m_sock_item, &list);
634 rds_send_sndbuf_remove(rs, rm); 636 rds_send_sndbuf_remove(rs, rm);
635 clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); 637 clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags);
636
637 /* If this is a RDMA operation, notify the app. */
638 __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED);
639 } 638 }
640 639
641 /* order flag updates with the rs lock */ 640 /* order flag updates with the rs lock */
@@ -644,9 +643,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
644 643
645 spin_unlock_irqrestore(&rs->rs_lock, flags); 644 spin_unlock_irqrestore(&rs->rs_lock, flags);
646 645
647 if (wake)
648 rds_wake_sk_sleep(rs);
649
650 conn = NULL; 646 conn = NULL;
651 647
652 /* now remove the messages from the conn list as needed */ 648 /* now remove the messages from the conn list as needed */
@@ -654,6 +650,10 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
654 /* We do this here rather than in the loop above, so that 650 /* We do this here rather than in the loop above, so that
655 * we don't have to nest m_rs_lock under rs->rs_lock */ 651 * we don't have to nest m_rs_lock under rs->rs_lock */
656 spin_lock_irqsave(&rm->m_rs_lock, flags2); 652 spin_lock_irqsave(&rm->m_rs_lock, flags2);
653 /* If this is a RDMA operation, notify the app. */
654 spin_lock(&rs->rs_lock);
655 __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED);
656 spin_unlock(&rs->rs_lock);
657 rm->m_rs = NULL; 657 rm->m_rs = NULL;
658 spin_unlock_irqrestore(&rm->m_rs_lock, flags2); 658 spin_unlock_irqrestore(&rm->m_rs_lock, flags2);
659 659
@@ -682,6 +682,9 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
682 if (conn) 682 if (conn)
683 spin_unlock_irqrestore(&conn->c_lock, flags); 683 spin_unlock_irqrestore(&conn->c_lock, flags);
684 684
685 if (wake)
686 rds_wake_sk_sleep(rs);
687
685 while (!list_empty(&list)) { 688 while (!list_empty(&list)) {
686 rm = list_entry(list.next, struct rds_message, m_sock_item); 689 rm = list_entry(list.next, struct rds_message, m_sock_item);
687 list_del_init(&rm->m_sock_item); 690 list_del_init(&rm->m_sock_item);
@@ -815,7 +818,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
815 int ret = 0; 818 int ret = 0;
816 int queued = 0, allocated_mr = 0; 819 int queued = 0, allocated_mr = 0;
817 int nonblock = msg->msg_flags & MSG_DONTWAIT; 820 int nonblock = msg->msg_flags & MSG_DONTWAIT;
818 long timeo = sock_rcvtimeo(sk, nonblock); 821 long timeo = sock_sndtimeo(sk, nonblock);
819 822
820 /* Mirror Linux UDP mirror of BSD error message compatibility */ 823 /* Mirror Linux UDP mirror of BSD error message compatibility */
821 /* XXX: Perhaps MSG_MORE someday */ 824 /* XXX: Perhaps MSG_MORE someday */
@@ -894,8 +897,10 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
894 queue_delayed_work(rds_wq, &conn->c_conn_w, 0); 897 queue_delayed_work(rds_wq, &conn->c_conn_w, 0);
895 898
896 ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); 899 ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs);
897 if (ret) 900 if (ret) {
901 rs->rs_seen_congestion = 1;
898 goto out; 902 goto out;
903 }
899 904
900 while (!rds_send_queue_rm(rs, conn, rm, rs->rs_bound_port, 905 while (!rds_send_queue_rm(rs, conn, rm, rs->rs_bound_port,
901 dport, &queued)) { 906 dport, &queued)) {
@@ -910,7 +915,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
910 goto out; 915 goto out;
911 } 916 }
912 917
913 timeo = wait_event_interruptible_timeout(*sk->sk_sleep, 918 timeo = wait_event_interruptible_timeout(*sk_sleep(sk),
914 rds_send_queue_rm(rs, conn, rm, 919 rds_send_queue_rm(rs, conn, rm,
915 rs->rs_bound_port, 920 rs->rs_bound_port,
916 dport, 921 dport,
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index b5198aee45d3..babf4577ff7d 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34#include <linux/in.h> 35#include <linux/in.h>
35#include <net/tcp.h> 36#include <net/tcp.h>
36 37
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index 211522f9a9a2..c519939e8da9 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -43,7 +43,7 @@ void rds_tcp_state_change(struct sock *sk)
43 struct rds_connection *conn; 43 struct rds_connection *conn;
44 struct rds_tcp_connection *tc; 44 struct rds_tcp_connection *tc;
45 45
46 read_lock(&sk->sk_callback_lock); 46 read_lock_bh(&sk->sk_callback_lock);
47 conn = sk->sk_user_data; 47 conn = sk->sk_user_data;
48 if (conn == NULL) { 48 if (conn == NULL) {
49 state_change = sk->sk_state_change; 49 state_change = sk->sk_state_change;
@@ -68,7 +68,7 @@ void rds_tcp_state_change(struct sock *sk)
68 break; 68 break;
69 } 69 }
70out: 70out:
71 read_unlock(&sk->sk_callback_lock); 71 read_unlock_bh(&sk->sk_callback_lock);
72 state_change(sk); 72 state_change(sk);
73} 73}
74 74
@@ -90,8 +90,8 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
90 90
91 ret = sock->ops->bind(sock, (struct sockaddr *)&src, sizeof(src)); 91 ret = sock->ops->bind(sock, (struct sockaddr *)&src, sizeof(src));
92 if (ret) { 92 if (ret) {
93 rdsdebug("bind failed with %d at address %u.%u.%u.%u\n", 93 rdsdebug("bind failed with %d at address %pI4\n",
94 ret, NIPQUAD(conn->c_laddr)); 94 ret, &conn->c_laddr);
95 goto out; 95 goto out;
96 } 96 }
97 97
@@ -108,8 +108,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
108 O_NONBLOCK); 108 O_NONBLOCK);
109 sock = NULL; 109 sock = NULL;
110 110
111 rdsdebug("connect to address %u.%u.%u.%u returned %d\n", 111 rdsdebug("connect to address %pI4 returned %d\n", &conn->c_faddr, ret);
112 NIPQUAD(conn->c_faddr), ret);
113 if (ret == -EINPROGRESS) 112 if (ret == -EINPROGRESS)
114 ret = 0; 113 ret = 0;
115 114
@@ -142,7 +141,7 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn)
142 141
143 release_sock(sock->sk); 142 release_sock(sock->sk);
144 sock_release(sock); 143 sock_release(sock);
145 }; 144 }
146 145
147 if (tc->t_tinc) { 146 if (tc->t_tinc) {
148 rds_inc_put(&tc->t_tinc->ti_inc); 147 rds_inc_put(&tc->t_tinc->ti_inc);
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 45474a436862..27844f231d10 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/gfp.h>
34#include <linux/in.h> 35#include <linux/in.h>
35#include <net/tcp.h> 36#include <net/tcp.h>
36 37
@@ -66,9 +67,9 @@ static int rds_tcp_accept_one(struct socket *sock)
66 67
67 inet = inet_sk(new_sock->sk); 68 inet = inet_sk(new_sock->sk);
68 69
69 rdsdebug("accepted tcp %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", 70 rdsdebug("accepted tcp %pI4:%u -> %pI4:%u\n",
70 NIPQUAD(inet->inet_saddr), ntohs(inet->inet_sport), 71 &inet->inet_saddr, ntohs(inet->inet_sport),
71 NIPQUAD(inet->inet_daddr), ntohs(inet->inet_dport)); 72 &inet->inet_daddr, ntohs(inet->inet_dport));
72 73
73 conn = rds_conn_create(inet->inet_saddr, inet->inet_daddr, 74 conn = rds_conn_create(inet->inet_saddr, inet->inet_daddr,
74 &rds_tcp_transport, GFP_KERNEL); 75 &rds_tcp_transport, GFP_KERNEL);
@@ -113,7 +114,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
113 114
114 rdsdebug("listen data ready sk %p\n", sk); 115 rdsdebug("listen data ready sk %p\n", sk);
115 116
116 read_lock(&sk->sk_callback_lock); 117 read_lock_bh(&sk->sk_callback_lock);
117 ready = sk->sk_user_data; 118 ready = sk->sk_user_data;
118 if (ready == NULL) { /* check for teardown race */ 119 if (ready == NULL) { /* check for teardown race */
119 ready = sk->sk_data_ready; 120 ready = sk->sk_data_ready;
@@ -130,7 +131,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
130 queue_work(rds_wq, &rds_tcp_listen_work); 131 queue_work(rds_wq, &rds_tcp_listen_work);
131 132
132out: 133out:
133 read_unlock(&sk->sk_callback_lock); 134 read_unlock_bh(&sk->sk_callback_lock);
134 ready(sk, bytes); 135 ready(sk, bytes);
135} 136}
136 137
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index c00dafffbb5a..e43797404102 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -31,6 +31,7 @@
31 * 31 *
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h>
34#include <net/tcp.h> 35#include <net/tcp.h>
35 36
36#include "rds.h" 37#include "rds.h"
@@ -97,6 +98,7 @@ int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
97 goto out; 98 goto out;
98 } 99 }
99 100
101 rds_stats_add(s_copy_to_user, to_copy);
100 size -= to_copy; 102 size -= to_copy;
101 ret += to_copy; 103 ret += to_copy;
102 skb_off += to_copy; 104 skb_off += to_copy;
@@ -322,7 +324,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
322 324
323 rdsdebug("data ready sk %p bytes %d\n", sk, bytes); 325 rdsdebug("data ready sk %p bytes %d\n", sk, bytes);
324 326
325 read_lock(&sk->sk_callback_lock); 327 read_lock_bh(&sk->sk_callback_lock);
326 conn = sk->sk_user_data; 328 conn = sk->sk_user_data;
327 if (conn == NULL) { /* check for teardown race */ 329 if (conn == NULL) { /* check for teardown race */
328 ready = sk->sk_data_ready; 330 ready = sk->sk_data_ready;
@@ -336,7 +338,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
336 if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) 338 if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM)
337 queue_delayed_work(rds_wq, &conn->c_recv_w, 0); 339 queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
338out: 340out:
339 read_unlock(&sk->sk_callback_lock); 341 read_unlock_bh(&sk->sk_callback_lock);
340 ready(sk, bytes); 342 ready(sk, bytes);
341} 343}
342 344
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c
index ab545e0cd5d6..2f012a07d94d 100644
--- a/net/rds/tcp_send.c
+++ b/net/rds/tcp_send.c
@@ -193,9 +193,9 @@ out:
193 rds_tcp_stats_inc(s_tcp_sndbuf_full); 193 rds_tcp_stats_inc(s_tcp_sndbuf_full);
194 ret = 0; 194 ret = 0;
195 } else { 195 } else {
196 printk(KERN_WARNING "RDS/tcp: send to %u.%u.%u.%u " 196 printk(KERN_WARNING "RDS/tcp: send to %pI4 "
197 "returned %d, disconnecting and reconnecting\n", 197 "returned %d, disconnecting and reconnecting\n",
198 NIPQUAD(conn->c_faddr), ret); 198 &conn->c_faddr, ret);
199 rds_conn_drop(conn); 199 rds_conn_drop(conn);
200 } 200 }
201 } 201 }
@@ -224,7 +224,7 @@ void rds_tcp_write_space(struct sock *sk)
224 struct rds_connection *conn; 224 struct rds_connection *conn;
225 struct rds_tcp_connection *tc; 225 struct rds_tcp_connection *tc;
226 226
227 read_lock(&sk->sk_callback_lock); 227 read_lock_bh(&sk->sk_callback_lock);
228 conn = sk->sk_user_data; 228 conn = sk->sk_user_data;
229 if (conn == NULL) { 229 if (conn == NULL) {
230 write_space = sk->sk_write_space; 230 write_space = sk->sk_write_space;
@@ -240,9 +240,11 @@ void rds_tcp_write_space(struct sock *sk)
240 tc->t_last_seen_una = rds_tcp_snd_una(tc); 240 tc->t_last_seen_una = rds_tcp_snd_una(tc);
241 rds_send_drop_acked(conn, rds_tcp_snd_una(tc), rds_tcp_is_acked); 241 rds_send_drop_acked(conn, rds_tcp_snd_una(tc), rds_tcp_is_acked);
242 242
243 queue_delayed_work(rds_wq, &conn->c_send_w, 0); 243 if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf)
244 queue_delayed_work(rds_wq, &conn->c_send_w, 0);
245
244out: 246out:
245 read_unlock(&sk->sk_callback_lock); 247 read_unlock_bh(&sk->sk_callback_lock);
246 248
247 /* 249 /*
248 * write_space is only called when data leaves tcp's send queue if 250 * write_space is only called when data leaves tcp's send queue if
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 00fa10e59af8..786c20eaaf5e 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -259,7 +259,7 @@ void rds_threads_exit(void)
259 259
260int __init rds_threads_init(void) 260int __init rds_threads_init(void)
261{ 261{
262 rds_wq = create_singlethread_workqueue("krdsd"); 262 rds_wq = create_workqueue("krdsd");
263 if (rds_wq == NULL) 263 if (rds_wq == NULL)
264 return -ENOMEM; 264 return -ENOMEM;
265 265