diff options
Diffstat (limited to 'net/rds')
-rw-r--r-- | net/rds/af_rds.c | 11 | ||||
-rw-r--r-- | net/rds/cong.c | 2 | ||||
-rw-r--r-- | net/rds/ib_cm.c | 3 | ||||
-rw-r--r-- | net/rds/ib_rdma.c | 5 | ||||
-rw-r--r-- | net/rds/ib_recv.c | 4 | ||||
-rw-r--r-- | net/rds/ib_send.c | 20 | ||||
-rw-r--r-- | net/rds/iw_cm.c | 4 | ||||
-rw-r--r-- | net/rds/iw_recv.c | 4 | ||||
-rw-r--r-- | net/rds/iw_send.c | 3 | ||||
-rw-r--r-- | net/rds/loop.c | 7 | ||||
-rw-r--r-- | net/rds/rdma.c | 4 | ||||
-rw-r--r-- | net/rds/rdma_transport.c | 5 | ||||
-rw-r--r-- | net/rds/rds.h | 4 | ||||
-rw-r--r-- | net/rds/recv.c | 2 | ||||
-rw-r--r-- | net/rds/send.c | 40 | ||||
-rw-r--r-- | net/rds/tcp_connect.c | 2 | ||||
-rw-r--r-- | net/rds/tcp_recv.c | 1 | ||||
-rw-r--r-- | net/rds/tcp_send.c | 4 | ||||
-rw-r--r-- | net/rds/threads.c | 2 |
19 files changed, 72 insertions, 55 deletions
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index f81862baf4d0..aebfecbdb841 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c | |||
@@ -158,9 +158,10 @@ static unsigned int rds_poll(struct file *file, struct socket *sock, | |||
158 | unsigned int mask = 0; | 158 | unsigned int mask = 0; |
159 | unsigned long flags; | 159 | unsigned long flags; |
160 | 160 | ||
161 | poll_wait(file, sk->sk_sleep, wait); | 161 | poll_wait(file, sk_sleep(sk), wait); |
162 | 162 | ||
163 | poll_wait(file, &rds_poll_waitq, wait); | 163 | if (rs->rs_seen_congestion) |
164 | poll_wait(file, &rds_poll_waitq, wait); | ||
164 | 165 | ||
165 | read_lock_irqsave(&rs->rs_recv_lock, flags); | 166 | read_lock_irqsave(&rs->rs_recv_lock, flags); |
166 | if (!rs->rs_cong_monitor) { | 167 | if (!rs->rs_cong_monitor) { |
@@ -182,6 +183,10 @@ static unsigned int rds_poll(struct file *file, struct socket *sock, | |||
182 | mask |= (POLLOUT | POLLWRNORM); | 183 | mask |= (POLLOUT | POLLWRNORM); |
183 | read_unlock_irqrestore(&rs->rs_recv_lock, flags); | 184 | read_unlock_irqrestore(&rs->rs_recv_lock, flags); |
184 | 185 | ||
186 | /* clear state any time we wake a seen-congested socket */ | ||
187 | if (mask) | ||
188 | rs->rs_seen_congestion = 0; | ||
189 | |||
185 | return mask; | 190 | return mask; |
186 | } | 191 | } |
187 | 192 | ||
@@ -447,7 +452,6 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len, | |||
447 | struct rds_info_lengths *lens) | 452 | struct rds_info_lengths *lens) |
448 | { | 453 | { |
449 | struct rds_sock *rs; | 454 | struct rds_sock *rs; |
450 | struct sock *sk; | ||
451 | struct rds_incoming *inc; | 455 | struct rds_incoming *inc; |
452 | unsigned long flags; | 456 | unsigned long flags; |
453 | unsigned int total = 0; | 457 | unsigned int total = 0; |
@@ -457,7 +461,6 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len, | |||
457 | spin_lock_irqsave(&rds_sock_lock, flags); | 461 | spin_lock_irqsave(&rds_sock_lock, flags); |
458 | 462 | ||
459 | list_for_each_entry(rs, &rds_sock_list, rs_item) { | 463 | list_for_each_entry(rs, &rds_sock_list, rs_item) { |
460 | sk = rds_rs_to_sk(rs); | ||
461 | read_lock(&rs->rs_recv_lock); | 464 | read_lock(&rs->rs_recv_lock); |
462 | 465 | ||
463 | /* 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 f1da27ceb064..0871a29f0780 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c | |||
@@ -219,8 +219,6 @@ void rds_cong_queue_updates(struct rds_cong_map *map) | |||
219 | spin_lock_irqsave(&rds_cong_lock, flags); | 219 | spin_lock_irqsave(&rds_cong_lock, flags); |
220 | 220 | ||
221 | 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) { |
222 | if (conn->c_loopback) | ||
223 | continue; | ||
224 | if (!test_and_set_bit(0, &conn->c_map_queued)) { | 222 | if (!test_and_set_bit(0, &conn->c_map_queued)) { |
225 | rds_stats_inc(s_cong_update_queued); | 223 | rds_stats_inc(s_cong_update_queued); |
226 | 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/ib_cm.c b/net/rds/ib_cm.c index 88d0856cb797..10ed0d55f759 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -204,9 +204,10 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data) | |||
204 | rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST); | 204 | rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST); |
205 | break; | 205 | break; |
206 | default: | 206 | default: |
207 | rds_ib_conn_error(conn, "RDS/IB: Fatal QP Event %u " | 207 | rdsdebug("Fatal QP Event %u " |
208 | "- connection %pI4->%pI4, reconnecting\n", | 208 | "- connection %pI4->%pI4, reconnecting\n", |
209 | event->event, &conn->c_laddr, &conn->c_faddr); | 209 | event->event, &conn->c_laddr, &conn->c_faddr); |
210 | rds_conn_drop(conn); | ||
210 | break; | 211 | break; |
211 | } | 212 | } |
212 | } | 213 | } |
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 059989fdb7d7..a54cd63f9e35 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c | |||
@@ -235,8 +235,8 @@ void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) | |||
235 | { | 235 | { |
236 | flush_workqueue(rds_wq); | 236 | flush_workqueue(rds_wq); |
237 | rds_ib_flush_mr_pool(pool, 1); | 237 | rds_ib_flush_mr_pool(pool, 1); |
238 | BUG_ON(atomic_read(&pool->item_count)); | 238 | WARN_ON(atomic_read(&pool->item_count)); |
239 | BUG_ON(atomic_read(&pool->free_pinned)); | 239 | WARN_ON(atomic_read(&pool->free_pinned)); |
240 | kfree(pool); | 240 | kfree(pool); |
241 | } | 241 | } |
242 | 242 | ||
@@ -441,6 +441,7 @@ static void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr) | |||
441 | 441 | ||
442 | /* FIXME we need a way to tell a r/w MR | 442 | /* FIXME we need a way to tell a r/w MR |
443 | * from a r/o MR */ | 443 | * from a r/o MR */ |
444 | BUG_ON(in_interrupt()); | ||
444 | set_page_dirty(page); | 445 | set_page_dirty(page); |
445 | put_page(page); | 446 | put_page(page); |
446 | } | 447 | } |
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index c7dd11b835f0..c74e9904a6b2 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
@@ -469,8 +469,8 @@ static void rds_ib_send_ack(struct rds_ib_connection *ic, unsigned int adv_credi | |||
469 | set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); | 469 | set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); |
470 | 470 | ||
471 | rds_ib_stats_inc(s_ib_ack_send_failure); | 471 | rds_ib_stats_inc(s_ib_ack_send_failure); |
472 | /* Need to finesse this later. */ | 472 | |
473 | BUG(); | 473 | rds_ib_conn_error(ic->conn, "sending ack failed\n"); |
474 | } else | 474 | } else |
475 | rds_ib_stats_inc(s_ib_ack_sent); | 475 | rds_ib_stats_inc(s_ib_ack_sent); |
476 | } | 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/iw_cm.c b/net/rds/iw_cm.c index 3e9460f935d8..a9d951b4fbae 100644 --- a/net/rds/iw_cm.c +++ b/net/rds/iw_cm.c | |||
@@ -157,9 +157,11 @@ static void rds_iw_qp_event_handler(struct ib_event *event, void *data) | |||
157 | case IB_EVENT_QP_REQ_ERR: | 157 | case IB_EVENT_QP_REQ_ERR: |
158 | case IB_EVENT_QP_FATAL: | 158 | case IB_EVENT_QP_FATAL: |
159 | default: | 159 | default: |
160 | 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", | ||
161 | event->event, &conn->c_laddr, | 162 | event->event, &conn->c_laddr, |
162 | &conn->c_faddr); | 163 | &conn->c_faddr); |
164 | rds_conn_drop(conn); | ||
163 | break; | 165 | break; |
164 | } | 166 | } |
165 | } | 167 | } |
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index da43ee840ca3..3d479067d54d 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c | |||
@@ -469,8 +469,8 @@ static void rds_iw_send_ack(struct rds_iw_connection *ic, unsigned int adv_credi | |||
469 | set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); | 469 | set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); |
470 | 470 | ||
471 | rds_iw_stats_inc(s_iw_ack_send_failure); | 471 | rds_iw_stats_inc(s_iw_ack_send_failure); |
472 | /* Need to finesse this later. */ | 472 | |
473 | BUG(); | 473 | rds_iw_conn_error(ic->conn, "sending ack failed\n"); |
474 | } else | 474 | } else |
475 | rds_iw_stats_inc(s_iw_ack_sent); | 475 | rds_iw_stats_inc(s_iw_ack_sent); |
476 | } | 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 0d7a159158b8..dd9879379457 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c | |||
@@ -81,16 +81,9 @@ static int rds_loop_xmit_cong_map(struct rds_connection *conn, | |||
81 | struct rds_cong_map *map, | 81 | struct rds_cong_map *map, |
82 | unsigned long offset) | 82 | unsigned long offset) |
83 | { | 83 | { |
84 | unsigned long i; | ||
85 | |||
86 | BUG_ON(offset); | 84 | BUG_ON(offset); |
87 | BUG_ON(map != conn->c_lcong); | 85 | BUG_ON(map != conn->c_lcong); |
88 | 86 | ||
89 | for (i = 0; i < RDS_CONG_MAP_PAGES; i++) { | ||
90 | memcpy((void *)conn->c_fcong->m_page_addrs[i], | ||
91 | (void *)map->m_page_addrs[i], PAGE_SIZE); | ||
92 | } | ||
93 | |||
94 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); | 87 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); |
95 | 88 | ||
96 | return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; | 89 | return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; |
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 5ce9437cad67..75fd13bb631b 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -439,8 +439,10 @@ void rds_rdma_free_op(struct rds_rdma_op *ro) | |||
439 | /* Mark page dirty if it was possibly modified, which | 439 | /* Mark page dirty if it was possibly modified, which |
440 | * is the case for a RDMA_READ which copies from remote | 440 | * is the case for a RDMA_READ which copies from remote |
441 | * to local memory */ | 441 | * to local memory */ |
442 | if (!ro->r_write) | 442 | if (!ro->r_write) { |
443 | BUG_ON(in_interrupt()); | ||
443 | set_page_dirty(page); | 444 | set_page_dirty(page); |
445 | } | ||
444 | put_page(page); | 446 | put_page(page); |
445 | } | 447 | } |
446 | 448 | ||
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 7b155081b4dc..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 | ||
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); | |||
490 | void rds_wake_sk_sleep(struct rds_sock *rs); | 492 | void rds_wake_sk_sleep(struct rds_sock *rs); |
491 | static inline void __rds_wake_sk_sleep(struct sock *sk) | 493 | static 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 e2a2b9344f7b..795a00b7f2cb 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -432,7 +432,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
432 | break; | 432 | break; |
433 | } | 433 | } |
434 | 434 | ||
435 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, | 435 | timeo = wait_event_interruptible_timeout(*sk_sleep(sk), |
436 | (!list_empty(&rs->rs_notify_queue) || | 436 | (!list_empty(&rs->rs_notify_queue) || |
437 | rs->rs_cong_notify || | 437 | rs->rs_cong_notify || |
438 | 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 f04b929ded92..9c1c6bcaa6c9 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -508,12 +508,13 @@ EXPORT_SYMBOL_GPL(rds_send_get_message); | |||
508 | */ | 508 | */ |
509 | void rds_send_remove_from_sock(struct list_head *messages, int status) | 509 | void rds_send_remove_from_sock(struct list_head *messages, int status) |
510 | { | 510 | { |
511 | unsigned long flags = 0; /* silence gcc :P */ | 511 | unsigned long flags; |
512 | struct rds_sock *rs = NULL; | 512 | struct rds_sock *rs = NULL; |
513 | struct rds_message *rm; | 513 | struct rds_message *rm; |
514 | 514 | ||
515 | local_irq_save(flags); | ||
516 | while (!list_empty(messages)) { | 515 | while (!list_empty(messages)) { |
516 | int was_on_sock = 0; | ||
517 | |||
517 | rm = list_entry(messages->next, struct rds_message, | 518 | rm = list_entry(messages->next, struct rds_message, |
518 | m_conn_item); | 519 | m_conn_item); |
519 | list_del_init(&rm->m_conn_item); | 520 | list_del_init(&rm->m_conn_item); |
@@ -528,20 +529,19 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) | |||
528 | * while we're messing with it. It does not prevent the | 529 | * while we're messing with it. It does not prevent the |
529 | * message from being removed from the socket, though. | 530 | * message from being removed from the socket, though. |
530 | */ | 531 | */ |
531 | spin_lock(&rm->m_rs_lock); | 532 | spin_lock_irqsave(&rm->m_rs_lock, flags); |
532 | if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) | 533 | if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) |
533 | goto unlock_and_drop; | 534 | goto unlock_and_drop; |
534 | 535 | ||
535 | if (rs != rm->m_rs) { | 536 | if (rs != rm->m_rs) { |
536 | if (rs) { | 537 | if (rs) { |
537 | spin_unlock(&rs->rs_lock); | ||
538 | rds_wake_sk_sleep(rs); | 538 | rds_wake_sk_sleep(rs); |
539 | sock_put(rds_rs_to_sk(rs)); | 539 | sock_put(rds_rs_to_sk(rs)); |
540 | } | 540 | } |
541 | rs = rm->m_rs; | 541 | rs = rm->m_rs; |
542 | spin_lock(&rs->rs_lock); | ||
543 | sock_hold(rds_rs_to_sk(rs)); | 542 | sock_hold(rds_rs_to_sk(rs)); |
544 | } | 543 | } |
544 | spin_lock(&rs->rs_lock); | ||
545 | 545 | ||
546 | 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)) { |
547 | struct rds_rdma_op *ro = rm->m_rdma_op; | 547 | struct rds_rdma_op *ro = rm->m_rdma_op; |
@@ -558,21 +558,22 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) | |||
558 | notifier->n_status = status; | 558 | notifier->n_status = status; |
559 | rm->m_rdma_op->r_notifier = NULL; | 559 | rm->m_rdma_op->r_notifier = NULL; |
560 | } | 560 | } |
561 | rds_message_put(rm); | 561 | was_on_sock = 1; |
562 | rm->m_rs = NULL; | 562 | rm->m_rs = NULL; |
563 | } | 563 | } |
564 | spin_unlock(&rs->rs_lock); | ||
564 | 565 | ||
565 | unlock_and_drop: | 566 | unlock_and_drop: |
566 | spin_unlock(&rm->m_rs_lock); | 567 | spin_unlock_irqrestore(&rm->m_rs_lock, flags); |
567 | rds_message_put(rm); | 568 | rds_message_put(rm); |
569 | if (was_on_sock) | ||
570 | rds_message_put(rm); | ||
568 | } | 571 | } |
569 | 572 | ||
570 | if (rs) { | 573 | if (rs) { |
571 | spin_unlock(&rs->rs_lock); | ||
572 | rds_wake_sk_sleep(rs); | 574 | rds_wake_sk_sleep(rs); |
573 | sock_put(rds_rs_to_sk(rs)); | 575 | sock_put(rds_rs_to_sk(rs)); |
574 | } | 576 | } |
575 | local_irq_restore(flags); | ||
576 | } | 577 | } |
577 | 578 | ||
578 | /* | 579 | /* |
@@ -634,9 +635,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
634 | list_move(&rm->m_sock_item, &list); | 635 | list_move(&rm->m_sock_item, &list); |
635 | rds_send_sndbuf_remove(rs, rm); | 636 | rds_send_sndbuf_remove(rs, rm); |
636 | clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); | 637 | clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); |
637 | |||
638 | /* If this is a RDMA operation, notify the app. */ | ||
639 | __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); | ||
640 | } | 638 | } |
641 | 639 | ||
642 | /* order flag updates with the rs lock */ | 640 | /* order flag updates with the rs lock */ |
@@ -645,9 +643,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
645 | 643 | ||
646 | spin_unlock_irqrestore(&rs->rs_lock, flags); | 644 | spin_unlock_irqrestore(&rs->rs_lock, flags); |
647 | 645 | ||
648 | if (wake) | ||
649 | rds_wake_sk_sleep(rs); | ||
650 | |||
651 | conn = NULL; | 646 | conn = NULL; |
652 | 647 | ||
653 | /* now remove the messages from the conn list as needed */ | 648 | /* now remove the messages from the conn list as needed */ |
@@ -655,6 +650,10 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
655 | /* 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 |
656 | * 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 */ |
657 | 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); | ||
658 | rm->m_rs = NULL; | 657 | rm->m_rs = NULL; |
659 | spin_unlock_irqrestore(&rm->m_rs_lock, flags2); | 658 | spin_unlock_irqrestore(&rm->m_rs_lock, flags2); |
660 | 659 | ||
@@ -683,6 +682,9 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
683 | if (conn) | 682 | if (conn) |
684 | spin_unlock_irqrestore(&conn->c_lock, flags); | 683 | spin_unlock_irqrestore(&conn->c_lock, flags); |
685 | 684 | ||
685 | if (wake) | ||
686 | rds_wake_sk_sleep(rs); | ||
687 | |||
686 | while (!list_empty(&list)) { | 688 | while (!list_empty(&list)) { |
687 | rm = list_entry(list.next, struct rds_message, m_sock_item); | 689 | rm = list_entry(list.next, struct rds_message, m_sock_item); |
688 | list_del_init(&rm->m_sock_item); | 690 | list_del_init(&rm->m_sock_item); |
@@ -816,7 +818,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
816 | int ret = 0; | 818 | int ret = 0; |
817 | int queued = 0, allocated_mr = 0; | 819 | int queued = 0, allocated_mr = 0; |
818 | int nonblock = msg->msg_flags & MSG_DONTWAIT; | 820 | int nonblock = msg->msg_flags & MSG_DONTWAIT; |
819 | long timeo = sock_rcvtimeo(sk, nonblock); | 821 | long timeo = sock_sndtimeo(sk, nonblock); |
820 | 822 | ||
821 | /* Mirror Linux UDP mirror of BSD error message compatibility */ | 823 | /* Mirror Linux UDP mirror of BSD error message compatibility */ |
822 | /* XXX: Perhaps MSG_MORE someday */ | 824 | /* XXX: Perhaps MSG_MORE someday */ |
@@ -895,8 +897,10 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
895 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); | 897 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); |
896 | 898 | ||
897 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); | 899 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); |
898 | if (ret) | 900 | if (ret) { |
901 | rs->rs_seen_congestion = 1; | ||
899 | goto out; | 902 | goto out; |
903 | } | ||
900 | 904 | ||
901 | 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, |
902 | dport, &queued)) { | 906 | dport, &queued)) { |
@@ -911,7 +915,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
911 | goto out; | 915 | goto out; |
912 | } | 916 | } |
913 | 917 | ||
914 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, | 918 | timeo = wait_event_interruptible_timeout(*sk_sleep(sk), |
915 | rds_send_queue_rm(rs, conn, rm, | 919 | rds_send_queue_rm(rs, conn, rm, |
916 | rs->rs_bound_port, | 920 | rs->rs_bound_port, |
917 | dport, | 921 | dport, |
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index 056256285987..c397524c039c 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -141,7 +141,7 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn) | |||
141 | 141 | ||
142 | release_sock(sock->sk); | 142 | release_sock(sock->sk); |
143 | sock_release(sock); | 143 | sock_release(sock); |
144 | }; | 144 | } |
145 | 145 | ||
146 | if (tc->t_tinc) { | 146 | if (tc->t_tinc) { |
147 | rds_inc_put(&tc->t_tinc->ti_inc); | 147 | rds_inc_put(&tc->t_tinc->ti_inc); |
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index e08ec912d8b0..1aba6878fa5d 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c | |||
@@ -98,6 +98,7 @@ int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | |||
98 | goto out; | 98 | goto out; |
99 | } | 99 | } |
100 | 100 | ||
101 | rds_stats_add(s_copy_to_user, to_copy); | ||
101 | size -= to_copy; | 102 | size -= to_copy; |
102 | ret += to_copy; | 103 | ret += to_copy; |
103 | skb_off += to_copy; | 104 | skb_off += to_copy; |
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index 34fdcc059e54..a28b895ff0d1 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c | |||
@@ -240,7 +240,9 @@ 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 | |||
244 | out: | 246 | out: |
245 | read_unlock(&sk->sk_callback_lock); | 247 | read_unlock(&sk->sk_callback_lock); |
246 | 248 | ||
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 | ||
260 | int __init rds_threads_init(void) | 260 | int __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 | ||