diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
commit | d7fc02c7bae7b1cf69269992cf880a43a350cdaa (patch) | |
tree | a43d56fa72913a1cc98a0bbebe054d08581b3a7c /net/rds | |
parent | ee1262dbc65ce0b6234a915d8432171e8d77f518 (diff) | |
parent | 28b4d5cc17c20786848cdc07b7ea237a309776bb (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1815 commits)
mac80211: fix reorder buffer release
iwmc3200wifi: Enable wimax core through module parameter
iwmc3200wifi: Add wifi-wimax coexistence mode as a module parameter
iwmc3200wifi: Coex table command does not expect a response
iwmc3200wifi: Update wiwi priority table
iwlwifi: driver version track kernel version
iwlwifi: indicate uCode type when fail dump error/event log
iwl3945: remove duplicated event logging code
b43: fix two warnings
ipw2100: fix rebooting hang with driver loaded
cfg80211: indent regulatory messages with spaces
iwmc3200wifi: fix NULL pointer dereference in pmkid update
mac80211: Fix TX status reporting for injected data frames
ath9k: enable 2GHz band only if the device supports it
airo: Fix integer overflow warning
rt2x00: Fix padding bug on L2PAD devices.
WE: Fix set events not propagated
b43legacy: avoid PPC fault during resume
b43: avoid PPC fault during resume
tcp: fix a timewait refcnt race
...
Fix up conflicts due to sysctl cleanups (dead sysctl_check code and
CTL_UNNUMBERED removed) in
kernel/sysctl_check.c
net/ipv4/sysctl_net_ipv4.c
net/ipv6/addrconf.c
net/sctp/sysctl.c
Diffstat (limited to 'net/rds')
-rw-r--r-- | net/rds/af_rds.c | 16 | ||||
-rw-r--r-- | net/rds/cong.c | 2 | ||||
-rw-r--r-- | net/rds/connection.c | 6 | ||||
-rw-r--r-- | net/rds/ib.h | 2 | ||||
-rw-r--r-- | net/rds/ib_cm.c | 6 | ||||
-rw-r--r-- | net/rds/ib_rdma.c | 9 | ||||
-rw-r--r-- | net/rds/ib_recv.c | 47 | ||||
-rw-r--r-- | net/rds/ib_send.c | 4 | ||||
-rw-r--r-- | net/rds/iw.h | 2 | ||||
-rw-r--r-- | net/rds/iw_cm.c | 2 | ||||
-rw-r--r-- | net/rds/iw_rdma.c | 9 | ||||
-rw-r--r-- | net/rds/iw_recv.c | 47 | ||||
-rw-r--r-- | net/rds/iw_send.c | 7 | ||||
-rw-r--r-- | net/rds/message.c | 3 | ||||
-rw-r--r-- | net/rds/rdma.c | 36 | ||||
-rw-r--r-- | net/rds/rdma.h | 1 | ||||
-rw-r--r-- | net/rds/recv.c | 11 | ||||
-rw-r--r-- | net/rds/send.c | 27 | ||||
-rw-r--r-- | net/rds/tcp_listen.c | 8 | ||||
-rw-r--r-- | net/rds/threads.c | 4 |
20 files changed, 155 insertions, 94 deletions
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 98e05382fd3c..853c52be781f 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c | |||
@@ -174,8 +174,8 @@ static unsigned int rds_poll(struct file *file, struct socket *sock, | |||
174 | mask |= (POLLIN | POLLRDNORM); | 174 | mask |= (POLLIN | POLLRDNORM); |
175 | spin_unlock(&rs->rs_lock); | 175 | spin_unlock(&rs->rs_lock); |
176 | } | 176 | } |
177 | if (!list_empty(&rs->rs_recv_queue) | 177 | if (!list_empty(&rs->rs_recv_queue) || |
178 | || !list_empty(&rs->rs_notify_queue)) | 178 | !list_empty(&rs->rs_notify_queue)) |
179 | mask |= (POLLIN | POLLRDNORM); | 179 | mask |= (POLLIN | POLLRDNORM); |
180 | if (rs->rs_snd_bytes < rds_sk_sndbuf(rs)) | 180 | if (rs->rs_snd_bytes < rds_sk_sndbuf(rs)) |
181 | mask |= (POLLOUT | POLLWRNORM); | 181 | mask |= (POLLOUT | POLLWRNORM); |
@@ -265,6 +265,9 @@ static int rds_setsockopt(struct socket *sock, int level, int optname, | |||
265 | case RDS_GET_MR: | 265 | case RDS_GET_MR: |
266 | ret = rds_get_mr(rs, optval, optlen); | 266 | ret = rds_get_mr(rs, optval, optlen); |
267 | break; | 267 | break; |
268 | case RDS_GET_MR_FOR_DEST: | ||
269 | ret = rds_get_mr_for_dest(rs, optval, optlen); | ||
270 | break; | ||
268 | case RDS_FREE_MR: | 271 | case RDS_FREE_MR: |
269 | ret = rds_free_mr(rs, optval, optlen); | 272 | ret = rds_free_mr(rs, optval, optlen); |
270 | break; | 273 | break; |
@@ -305,8 +308,8 @@ static int rds_getsockopt(struct socket *sock, int level, int optname, | |||
305 | if (len < sizeof(int)) | 308 | if (len < sizeof(int)) |
306 | ret = -EINVAL; | 309 | ret = -EINVAL; |
307 | else | 310 | else |
308 | if (put_user(rs->rs_recverr, (int __user *) optval) | 311 | if (put_user(rs->rs_recverr, (int __user *) optval) || |
309 | || put_user(sizeof(int), optlen)) | 312 | put_user(sizeof(int), optlen)) |
310 | ret = -EFAULT; | 313 | ret = -EFAULT; |
311 | else | 314 | else |
312 | ret = 0; | 315 | ret = 0; |
@@ -407,7 +410,8 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol) | |||
407 | return 0; | 410 | return 0; |
408 | } | 411 | } |
409 | 412 | ||
410 | static int rds_create(struct net *net, struct socket *sock, int protocol) | 413 | static int rds_create(struct net *net, struct socket *sock, int protocol, |
414 | int kern) | ||
411 | { | 415 | { |
412 | struct sock *sk; | 416 | struct sock *sk; |
413 | 417 | ||
@@ -431,7 +435,7 @@ void rds_sock_put(struct rds_sock *rs) | |||
431 | sock_put(rds_rs_to_sk(rs)); | 435 | sock_put(rds_rs_to_sk(rs)); |
432 | } | 436 | } |
433 | 437 | ||
434 | static struct net_proto_family rds_family_ops = { | 438 | static const struct net_proto_family rds_family_ops = { |
435 | .family = AF_RDS, | 439 | .family = AF_RDS, |
436 | .create = rds_create, | 440 | .create = rds_create, |
437 | .owner = THIS_MODULE, | 441 | .owner = THIS_MODULE, |
diff --git a/net/rds/cong.c b/net/rds/cong.c index dd2711df640b..6d06cac2649c 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c | |||
@@ -218,6 +218,8 @@ void rds_cong_queue_updates(struct rds_cong_map *map) | |||
218 | spin_lock_irqsave(&rds_cong_lock, flags); | 218 | spin_lock_irqsave(&rds_cong_lock, flags); |
219 | 219 | ||
220 | list_for_each_entry(conn, &map->m_conn_list, c_map_item) { | 220 | list_for_each_entry(conn, &map->m_conn_list, c_map_item) { |
221 | if (conn->c_loopback) | ||
222 | continue; | ||
221 | if (!test_and_set_bit(0, &conn->c_map_queued)) { | 223 | if (!test_and_set_bit(0, &conn->c_map_queued)) { |
222 | rds_stats_inc(s_cong_update_queued); | 224 | rds_stats_inc(s_cong_update_queued); |
223 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 225 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
diff --git a/net/rds/connection.c b/net/rds/connection.c index cc8b568c0c84..278f607ab603 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
@@ -133,10 +133,8 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, | |||
133 | 133 | ||
134 | spin_lock_irqsave(&rds_conn_lock, flags); | 134 | spin_lock_irqsave(&rds_conn_lock, flags); |
135 | conn = rds_conn_lookup(head, laddr, faddr, trans); | 135 | conn = rds_conn_lookup(head, laddr, faddr, trans); |
136 | if (conn | 136 | if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport && |
137 | && conn->c_loopback | 137 | !is_outgoing) { |
138 | && conn->c_trans != &rds_loop_transport | ||
139 | && !is_outgoing) { | ||
140 | /* This is a looped back IB connection, and we're | 138 | /* This is a looped back IB connection, and we're |
141 | * called by the code handling the incoming connect. | 139 | * called by the code handling the incoming connect. |
142 | * We need a second connection object into which we | 140 | * We need a second connection object into which we |
diff --git a/net/rds/ib.h b/net/rds/ib.h index 1378b854cac0..64df4e79b29f 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h | |||
@@ -98,6 +98,7 @@ struct rds_ib_connection { | |||
98 | struct rds_ib_send_work *i_sends; | 98 | struct rds_ib_send_work *i_sends; |
99 | 99 | ||
100 | /* rx */ | 100 | /* rx */ |
101 | struct tasklet_struct i_recv_tasklet; | ||
101 | struct mutex i_recv_mutex; | 102 | struct mutex i_recv_mutex; |
102 | struct rds_ib_work_ring i_recv_ring; | 103 | struct rds_ib_work_ring i_recv_ring; |
103 | struct rds_ib_incoming *i_ibinc; | 104 | struct rds_ib_incoming *i_ibinc; |
@@ -303,6 +304,7 @@ void rds_ib_inc_free(struct rds_incoming *inc); | |||
303 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, | 304 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, |
304 | size_t size); | 305 | size_t size); |
305 | void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context); | 306 | void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context); |
307 | void rds_ib_recv_tasklet_fn(unsigned long data); | ||
306 | void rds_ib_recv_init_ring(struct rds_ib_connection *ic); | 308 | void rds_ib_recv_init_ring(struct rds_ib_connection *ic); |
307 | void rds_ib_recv_clear_ring(struct rds_ib_connection *ic); | 309 | void rds_ib_recv_clear_ring(struct rds_ib_connection *ic); |
308 | void rds_ib_recv_init_ack(struct rds_ib_connection *ic); | 310 | void rds_ib_recv_init_ack(struct rds_ib_connection *ic); |
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index c2d372f13dbb..647cb8ffc39b 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -377,8 +377,8 @@ static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event) | |||
377 | } | 377 | } |
378 | 378 | ||
379 | /* Even if len is crap *now* I still want to check it. -ASG */ | 379 | /* Even if len is crap *now* I still want to check it. -ASG */ |
380 | if (event->param.conn.private_data_len < sizeof (*dp) | 380 | if (event->param.conn.private_data_len < sizeof (*dp) || |
381 | || dp->dp_protocol_major == 0) | 381 | dp->dp_protocol_major == 0) |
382 | return RDS_PROTOCOL_3_0; | 382 | return RDS_PROTOCOL_3_0; |
383 | 383 | ||
384 | common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS; | 384 | common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS; |
@@ -694,6 +694,8 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
694 | return -ENOMEM; | 694 | return -ENOMEM; |
695 | 695 | ||
696 | INIT_LIST_HEAD(&ic->ib_node); | 696 | INIT_LIST_HEAD(&ic->ib_node); |
697 | tasklet_init(&ic->i_recv_tasklet, rds_ib_recv_tasklet_fn, | ||
698 | (unsigned long) ic); | ||
697 | mutex_init(&ic->i_recv_mutex); | 699 | mutex_init(&ic->i_recv_mutex); |
698 | #ifndef KERNEL_HAS_ATOMIC64 | 700 | #ifndef KERNEL_HAS_ATOMIC64 |
699 | spin_lock_init(&ic->i_ack_lock); | 701 | spin_lock_init(&ic->i_ack_lock); |
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index ef3ab5b7283e..4b0da865a72c 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c | |||
@@ -187,11 +187,8 @@ void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) | |||
187 | INIT_LIST_HEAD(list); | 187 | INIT_LIST_HEAD(list); |
188 | spin_unlock_irq(list_lock); | 188 | spin_unlock_irq(list_lock); |
189 | 189 | ||
190 | list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node) { | 190 | list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node) |
191 | if (ic->conn->c_passive) | ||
192 | rds_conn_destroy(ic->conn->c_passive); | ||
193 | rds_conn_destroy(ic->conn); | 191 | rds_conn_destroy(ic->conn); |
194 | } | ||
195 | } | 192 | } |
196 | 193 | ||
197 | struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev) | 194 | struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev) |
@@ -573,8 +570,8 @@ void rds_ib_free_mr(void *trans_private, int invalidate) | |||
573 | spin_unlock_irqrestore(&pool->list_lock, flags); | 570 | spin_unlock_irqrestore(&pool->list_lock, flags); |
574 | 571 | ||
575 | /* If we've pinned too many pages, request a flush */ | 572 | /* If we've pinned too many pages, request a flush */ |
576 | if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned | 573 | if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || |
577 | || atomic_read(&pool->dirty_count) >= pool->max_items / 10) | 574 | atomic_read(&pool->dirty_count) >= pool->max_items / 10) |
578 | queue_work(rds_wq, &pool->flush_worker); | 575 | queue_work(rds_wq, &pool->flush_worker); |
579 | 576 | ||
580 | if (invalidate) { | 577 | if (invalidate) { |
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index cd7a6cfcab03..04dc0d3f3c95 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
@@ -143,15 +143,16 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, | |||
143 | int ret = -ENOMEM; | 143 | int ret = -ENOMEM; |
144 | 144 | ||
145 | if (recv->r_ibinc == NULL) { | 145 | if (recv->r_ibinc == NULL) { |
146 | if (atomic_read(&rds_ib_allocation) >= rds_ib_sysctl_max_recv_allocation) { | 146 | if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) { |
147 | rds_ib_stats_inc(s_ib_rx_alloc_limit); | 147 | rds_ib_stats_inc(s_ib_rx_alloc_limit); |
148 | goto out; | 148 | goto out; |
149 | } | 149 | } |
150 | recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, | 150 | recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, |
151 | kptr_gfp); | 151 | kptr_gfp); |
152 | if (recv->r_ibinc == NULL) | 152 | if (recv->r_ibinc == NULL) { |
153 | atomic_dec(&rds_ib_allocation); | ||
153 | goto out; | 154 | goto out; |
154 | atomic_inc(&rds_ib_allocation); | 155 | } |
155 | INIT_LIST_HEAD(&recv->r_ibinc->ii_frags); | 156 | INIT_LIST_HEAD(&recv->r_ibinc->ii_frags); |
156 | rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); | 157 | rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); |
157 | } | 158 | } |
@@ -229,8 +230,8 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, | |||
229 | int ret = 0; | 230 | int ret = 0; |
230 | u32 pos; | 231 | u32 pos; |
231 | 232 | ||
232 | while ((prefill || rds_conn_up(conn)) | 233 | while ((prefill || rds_conn_up(conn)) && |
233 | && rds_ib_ring_alloc(&ic->i_recv_ring, 1, &pos)) { | 234 | rds_ib_ring_alloc(&ic->i_recv_ring, 1, &pos)) { |
234 | if (pos >= ic->i_recv_ring.w_nr) { | 235 | if (pos >= ic->i_recv_ring.w_nr) { |
235 | printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n", | 236 | printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n", |
236 | pos); | 237 | pos); |
@@ -770,10 +771,10 @@ static void rds_ib_process_recv(struct rds_connection *conn, | |||
770 | hdr = &ibinc->ii_inc.i_hdr; | 771 | hdr = &ibinc->ii_inc.i_hdr; |
771 | /* We can't just use memcmp here; fragments of a | 772 | /* We can't just use memcmp here; fragments of a |
772 | * single message may carry different ACKs */ | 773 | * single message may carry different ACKs */ |
773 | if (hdr->h_sequence != ihdr->h_sequence | 774 | if (hdr->h_sequence != ihdr->h_sequence || |
774 | || hdr->h_len != ihdr->h_len | 775 | hdr->h_len != ihdr->h_len || |
775 | || hdr->h_sport != ihdr->h_sport | 776 | hdr->h_sport != ihdr->h_sport || |
776 | || hdr->h_dport != ihdr->h_dport) { | 777 | hdr->h_dport != ihdr->h_dport) { |
777 | rds_ib_conn_error(conn, | 778 | rds_ib_conn_error(conn, |
778 | "fragment header mismatch; forcing reconnect\n"); | 779 | "fragment header mismatch; forcing reconnect\n"); |
779 | return; | 780 | return; |
@@ -824,17 +825,22 @@ void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context) | |||
824 | { | 825 | { |
825 | struct rds_connection *conn = context; | 826 | struct rds_connection *conn = context; |
826 | struct rds_ib_connection *ic = conn->c_transport_data; | 827 | struct rds_ib_connection *ic = conn->c_transport_data; |
827 | struct ib_wc wc; | ||
828 | struct rds_ib_ack_state state = { 0, }; | ||
829 | struct rds_ib_recv_work *recv; | ||
830 | 828 | ||
831 | rdsdebug("conn %p cq %p\n", conn, cq); | 829 | rdsdebug("conn %p cq %p\n", conn, cq); |
832 | 830 | ||
833 | rds_ib_stats_inc(s_ib_rx_cq_call); | 831 | rds_ib_stats_inc(s_ib_rx_cq_call); |
834 | 832 | ||
835 | ib_req_notify_cq(cq, IB_CQ_SOLICITED); | 833 | tasklet_schedule(&ic->i_recv_tasklet); |
834 | } | ||
835 | |||
836 | static inline void rds_poll_cq(struct rds_ib_connection *ic, | ||
837 | struct rds_ib_ack_state *state) | ||
838 | { | ||
839 | struct rds_connection *conn = ic->conn; | ||
840 | struct ib_wc wc; | ||
841 | struct rds_ib_recv_work *recv; | ||
836 | 842 | ||
837 | while (ib_poll_cq(cq, 1, &wc) > 0) { | 843 | while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) { |
838 | rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", | 844 | rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", |
839 | (unsigned long long)wc.wr_id, wc.status, wc.byte_len, | 845 | (unsigned long long)wc.wr_id, wc.status, wc.byte_len, |
840 | be32_to_cpu(wc.ex.imm_data)); | 846 | be32_to_cpu(wc.ex.imm_data)); |
@@ -852,7 +858,7 @@ void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context) | |||
852 | if (rds_conn_up(conn) || rds_conn_connecting(conn)) { | 858 | if (rds_conn_up(conn) || rds_conn_connecting(conn)) { |
853 | /* We expect errors as the qp is drained during shutdown */ | 859 | /* We expect errors as the qp is drained during shutdown */ |
854 | if (wc.status == IB_WC_SUCCESS) { | 860 | if (wc.status == IB_WC_SUCCESS) { |
855 | rds_ib_process_recv(conn, recv, wc.byte_len, &state); | 861 | rds_ib_process_recv(conn, recv, wc.byte_len, state); |
856 | } else { | 862 | } else { |
857 | rds_ib_conn_error(conn, "recv completion on " | 863 | rds_ib_conn_error(conn, "recv completion on " |
858 | "%pI4 had status %u, disconnecting and " | 864 | "%pI4 had status %u, disconnecting and " |
@@ -863,6 +869,17 @@ void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context) | |||
863 | 869 | ||
864 | rds_ib_ring_free(&ic->i_recv_ring, 1); | 870 | rds_ib_ring_free(&ic->i_recv_ring, 1); |
865 | } | 871 | } |
872 | } | ||
873 | |||
874 | void rds_ib_recv_tasklet_fn(unsigned long data) | ||
875 | { | ||
876 | struct rds_ib_connection *ic = (struct rds_ib_connection *) data; | ||
877 | struct rds_connection *conn = ic->conn; | ||
878 | struct rds_ib_ack_state state = { 0, }; | ||
879 | |||
880 | rds_poll_cq(ic, &state); | ||
881 | ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); | ||
882 | rds_poll_cq(ic, &state); | ||
866 | 883 | ||
867 | if (state.ack_next_valid) | 884 | if (state.ack_next_valid) |
868 | rds_ib_set_ack(ic, state.ack_next, state.ack_required); | 885 | rds_ib_set_ack(ic, state.ack_next, state.ack_required); |
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 23bf830db2d5..a10fab6886d1 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c | |||
@@ -252,8 +252,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) | |||
252 | 252 | ||
253 | rds_ib_ring_free(&ic->i_send_ring, completed); | 253 | rds_ib_ring_free(&ic->i_send_ring, completed); |
254 | 254 | ||
255 | if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) | 255 | if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) || |
256 | || test_bit(0, &conn->c_map_queued)) | 256 | test_bit(0, &conn->c_map_queued)) |
257 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 257 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
258 | 258 | ||
259 | /* We expect errors as the qp is drained during shutdown */ | 259 | /* We expect errors as the qp is drained during shutdown */ |
diff --git a/net/rds/iw.h b/net/rds/iw.h index dd72b62bd506..eef2f0c28476 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h | |||
@@ -119,6 +119,7 @@ struct rds_iw_connection { | |||
119 | struct rds_iw_send_work *i_sends; | 119 | struct rds_iw_send_work *i_sends; |
120 | 120 | ||
121 | /* rx */ | 121 | /* rx */ |
122 | struct tasklet_struct i_recv_tasklet; | ||
122 | struct mutex i_recv_mutex; | 123 | struct mutex i_recv_mutex; |
123 | struct rds_iw_work_ring i_recv_ring; | 124 | struct rds_iw_work_ring i_recv_ring; |
124 | struct rds_iw_incoming *i_iwinc; | 125 | struct rds_iw_incoming *i_iwinc; |
@@ -330,6 +331,7 @@ void rds_iw_inc_free(struct rds_incoming *inc); | |||
330 | int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, | 331 | int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, |
331 | size_t size); | 332 | size_t size); |
332 | void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context); | 333 | void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context); |
334 | void rds_iw_recv_tasklet_fn(unsigned long data); | ||
333 | void rds_iw_recv_init_ring(struct rds_iw_connection *ic); | 335 | void rds_iw_recv_init_ring(struct rds_iw_connection *ic); |
334 | void rds_iw_recv_clear_ring(struct rds_iw_connection *ic); | 336 | void rds_iw_recv_clear_ring(struct rds_iw_connection *ic); |
335 | void rds_iw_recv_init_ack(struct rds_iw_connection *ic); | 337 | void rds_iw_recv_init_ack(struct rds_iw_connection *ic); |
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c index a416b0d492b1..394cf6b4d0aa 100644 --- a/net/rds/iw_cm.c +++ b/net/rds/iw_cm.c | |||
@@ -696,6 +696,8 @@ int rds_iw_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
696 | return -ENOMEM; | 696 | return -ENOMEM; |
697 | 697 | ||
698 | INIT_LIST_HEAD(&ic->iw_node); | 698 | INIT_LIST_HEAD(&ic->iw_node); |
699 | tasklet_init(&ic->i_recv_tasklet, rds_iw_recv_tasklet_fn, | ||
700 | (unsigned long) ic); | ||
699 | mutex_init(&ic->i_recv_mutex); | 701 | mutex_init(&ic->i_recv_mutex); |
700 | #ifndef KERNEL_HAS_ATOMIC64 | 702 | #ifndef KERNEL_HAS_ATOMIC64 |
701 | spin_lock_init(&ic->i_ack_lock); | 703 | spin_lock_init(&ic->i_ack_lock); |
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index de4a1b16bf7b..9eda11cca956 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c | |||
@@ -245,11 +245,8 @@ void __rds_iw_destroy_conns(struct list_head *list, spinlock_t *list_lock) | |||
245 | INIT_LIST_HEAD(list); | 245 | INIT_LIST_HEAD(list); |
246 | spin_unlock_irq(list_lock); | 246 | spin_unlock_irq(list_lock); |
247 | 247 | ||
248 | list_for_each_entry_safe(ic, _ic, &tmp_list, iw_node) { | 248 | list_for_each_entry_safe(ic, _ic, &tmp_list, iw_node) |
249 | if (ic->conn->c_passive) | ||
250 | rds_conn_destroy(ic->conn->c_passive); | ||
251 | rds_conn_destroy(ic->conn); | 249 | rds_conn_destroy(ic->conn); |
252 | } | ||
253 | } | 250 | } |
254 | 251 | ||
255 | static void rds_iw_set_scatterlist(struct rds_iw_scatterlist *sg, | 252 | static void rds_iw_set_scatterlist(struct rds_iw_scatterlist *sg, |
@@ -576,8 +573,8 @@ void rds_iw_free_mr(void *trans_private, int invalidate) | |||
576 | rds_iw_free_fastreg(pool, ibmr); | 573 | rds_iw_free_fastreg(pool, ibmr); |
577 | 574 | ||
578 | /* If we've pinned too many pages, request a flush */ | 575 | /* If we've pinned too many pages, request a flush */ |
579 | if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned | 576 | if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || |
580 | || atomic_read(&pool->dirty_count) >= pool->max_items / 10) | 577 | atomic_read(&pool->dirty_count) >= pool->max_items / 10) |
581 | queue_work(rds_wq, &pool->flush_worker); | 578 | queue_work(rds_wq, &pool->flush_worker); |
582 | 579 | ||
583 | if (invalidate) { | 580 | if (invalidate) { |
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index 8683f5f66c4b..54af7d6b92da 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c | |||
@@ -143,15 +143,16 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn, | |||
143 | int ret = -ENOMEM; | 143 | int ret = -ENOMEM; |
144 | 144 | ||
145 | if (recv->r_iwinc == NULL) { | 145 | if (recv->r_iwinc == NULL) { |
146 | if (atomic_read(&rds_iw_allocation) >= rds_iw_sysctl_max_recv_allocation) { | 146 | if (!atomic_add_unless(&rds_iw_allocation, 1, rds_iw_sysctl_max_recv_allocation)) { |
147 | rds_iw_stats_inc(s_iw_rx_alloc_limit); | 147 | rds_iw_stats_inc(s_iw_rx_alloc_limit); |
148 | goto out; | 148 | goto out; |
149 | } | 149 | } |
150 | recv->r_iwinc = kmem_cache_alloc(rds_iw_incoming_slab, | 150 | recv->r_iwinc = kmem_cache_alloc(rds_iw_incoming_slab, |
151 | kptr_gfp); | 151 | kptr_gfp); |
152 | if (recv->r_iwinc == NULL) | 152 | if (recv->r_iwinc == NULL) { |
153 | atomic_dec(&rds_iw_allocation); | ||
153 | goto out; | 154 | goto out; |
154 | atomic_inc(&rds_iw_allocation); | 155 | } |
155 | INIT_LIST_HEAD(&recv->r_iwinc->ii_frags); | 156 | INIT_LIST_HEAD(&recv->r_iwinc->ii_frags); |
156 | rds_inc_init(&recv->r_iwinc->ii_inc, conn, conn->c_faddr); | 157 | rds_inc_init(&recv->r_iwinc->ii_inc, conn, conn->c_faddr); |
157 | } | 158 | } |
@@ -229,8 +230,8 @@ int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, | |||
229 | int ret = 0; | 230 | int ret = 0; |
230 | u32 pos; | 231 | u32 pos; |
231 | 232 | ||
232 | while ((prefill || rds_conn_up(conn)) | 233 | while ((prefill || rds_conn_up(conn)) && |
233 | && rds_iw_ring_alloc(&ic->i_recv_ring, 1, &pos)) { | 234 | rds_iw_ring_alloc(&ic->i_recv_ring, 1, &pos)) { |
234 | if (pos >= ic->i_recv_ring.w_nr) { | 235 | if (pos >= ic->i_recv_ring.w_nr) { |
235 | printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n", | 236 | printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n", |
236 | pos); | 237 | pos); |
@@ -729,10 +730,10 @@ static void rds_iw_process_recv(struct rds_connection *conn, | |||
729 | hdr = &iwinc->ii_inc.i_hdr; | 730 | hdr = &iwinc->ii_inc.i_hdr; |
730 | /* We can't just use memcmp here; fragments of a | 731 | /* We can't just use memcmp here; fragments of a |
731 | * single message may carry different ACKs */ | 732 | * single message may carry different ACKs */ |
732 | if (hdr->h_sequence != ihdr->h_sequence | 733 | if (hdr->h_sequence != ihdr->h_sequence || |
733 | || hdr->h_len != ihdr->h_len | 734 | hdr->h_len != ihdr->h_len || |
734 | || hdr->h_sport != ihdr->h_sport | 735 | hdr->h_sport != ihdr->h_sport || |
735 | || hdr->h_dport != ihdr->h_dport) { | 736 | hdr->h_dport != ihdr->h_dport) { |
736 | rds_iw_conn_error(conn, | 737 | rds_iw_conn_error(conn, |
737 | "fragment header mismatch; forcing reconnect\n"); | 738 | "fragment header mismatch; forcing reconnect\n"); |
738 | return; | 739 | return; |
@@ -783,17 +784,22 @@ void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context) | |||
783 | { | 784 | { |
784 | struct rds_connection *conn = context; | 785 | struct rds_connection *conn = context; |
785 | struct rds_iw_connection *ic = conn->c_transport_data; | 786 | struct rds_iw_connection *ic = conn->c_transport_data; |
786 | struct ib_wc wc; | ||
787 | struct rds_iw_ack_state state = { 0, }; | ||
788 | struct rds_iw_recv_work *recv; | ||
789 | 787 | ||
790 | rdsdebug("conn %p cq %p\n", conn, cq); | 788 | rdsdebug("conn %p cq %p\n", conn, cq); |
791 | 789 | ||
792 | rds_iw_stats_inc(s_iw_rx_cq_call); | 790 | rds_iw_stats_inc(s_iw_rx_cq_call); |
793 | 791 | ||
794 | ib_req_notify_cq(cq, IB_CQ_SOLICITED); | 792 | tasklet_schedule(&ic->i_recv_tasklet); |
793 | } | ||
794 | |||
795 | static inline void rds_poll_cq(struct rds_iw_connection *ic, | ||
796 | struct rds_iw_ack_state *state) | ||
797 | { | ||
798 | struct rds_connection *conn = ic->conn; | ||
799 | struct ib_wc wc; | ||
800 | struct rds_iw_recv_work *recv; | ||
795 | 801 | ||
796 | while (ib_poll_cq(cq, 1, &wc) > 0) { | 802 | while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) { |
797 | rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", | 803 | rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", |
798 | (unsigned long long)wc.wr_id, wc.status, wc.byte_len, | 804 | (unsigned long long)wc.wr_id, wc.status, wc.byte_len, |
799 | be32_to_cpu(wc.ex.imm_data)); | 805 | be32_to_cpu(wc.ex.imm_data)); |
@@ -811,7 +817,7 @@ void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context) | |||
811 | if (rds_conn_up(conn) || rds_conn_connecting(conn)) { | 817 | if (rds_conn_up(conn) || rds_conn_connecting(conn)) { |
812 | /* We expect errors as the qp is drained during shutdown */ | 818 | /* We expect errors as the qp is drained during shutdown */ |
813 | if (wc.status == IB_WC_SUCCESS) { | 819 | if (wc.status == IB_WC_SUCCESS) { |
814 | rds_iw_process_recv(conn, recv, wc.byte_len, &state); | 820 | rds_iw_process_recv(conn, recv, wc.byte_len, state); |
815 | } else { | 821 | } else { |
816 | rds_iw_conn_error(conn, "recv completion on " | 822 | rds_iw_conn_error(conn, "recv completion on " |
817 | "%pI4 had status %u, disconnecting and " | 823 | "%pI4 had status %u, disconnecting and " |
@@ -822,6 +828,17 @@ void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context) | |||
822 | 828 | ||
823 | rds_iw_ring_free(&ic->i_recv_ring, 1); | 829 | rds_iw_ring_free(&ic->i_recv_ring, 1); |
824 | } | 830 | } |
831 | } | ||
832 | |||
833 | void rds_iw_recv_tasklet_fn(unsigned long data) | ||
834 | { | ||
835 | struct rds_iw_connection *ic = (struct rds_iw_connection *) data; | ||
836 | struct rds_connection *conn = ic->conn; | ||
837 | struct rds_iw_ack_state state = { 0, }; | ||
838 | |||
839 | rds_poll_cq(ic, &state); | ||
840 | ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); | ||
841 | rds_poll_cq(ic, &state); | ||
825 | 842 | ||
826 | if (state.ack_next_valid) | 843 | if (state.ack_next_valid) |
827 | rds_iw_set_ack(ic, state.ack_next, state.ack_required); | 844 | rds_iw_set_ack(ic, state.ack_next, state.ack_required); |
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 1f5abe3cf2b4..1379e9d66a78 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c | |||
@@ -288,8 +288,8 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context) | |||
288 | 288 | ||
289 | rds_iw_ring_free(&ic->i_send_ring, completed); | 289 | rds_iw_ring_free(&ic->i_send_ring, completed); |
290 | 290 | ||
291 | if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) | 291 | if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) || |
292 | || test_bit(0, &conn->c_map_queued)) | 292 | test_bit(0, &conn->c_map_queued)) |
293 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 293 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
294 | 294 | ||
295 | /* We expect errors as the qp is drained during shutdown */ | 295 | /* We expect errors as the qp is drained during shutdown */ |
@@ -519,8 +519,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
519 | BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header)); | 519 | BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header)); |
520 | 520 | ||
521 | /* Fastreg support */ | 521 | /* Fastreg support */ |
522 | if (rds_rdma_cookie_key(rm->m_rdma_cookie) | 522 | if (rds_rdma_cookie_key(rm->m_rdma_cookie) && !ic->i_fastreg_posted) { |
523 | && !ic->i_fastreg_posted) { | ||
524 | ret = -EAGAIN; | 523 | ret = -EAGAIN; |
525 | goto out; | 524 | goto out; |
526 | } | 525 | } |
diff --git a/net/rds/message.c b/net/rds/message.c index ca50a8ec9742..73e600ffd87f 100644 --- a/net/rds/message.c +++ b/net/rds/message.c | |||
@@ -122,8 +122,7 @@ int rds_message_add_extension(struct rds_header *hdr, | |||
122 | if (hdr->h_exthdr[0] != RDS_EXTHDR_NONE) | 122 | if (hdr->h_exthdr[0] != RDS_EXTHDR_NONE) |
123 | return 0; | 123 | return 0; |
124 | 124 | ||
125 | if (type >= __RDS_EXTHDR_MAX | 125 | if (type >= __RDS_EXTHDR_MAX || len != rds_exthdr_size[type]) |
126 | || len != rds_exthdr_size[type]) | ||
127 | return 0; | 126 | return 0; |
128 | 127 | ||
129 | if (ext_len >= RDS_HEADER_EXT_SPACE) | 128 | if (ext_len >= RDS_HEADER_EXT_SPACE) |
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 8dc83d2caa58..4c64daa1f5d5 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -317,6 +317,30 @@ int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen) | |||
317 | return __rds_rdma_map(rs, &args, NULL, NULL); | 317 | return __rds_rdma_map(rs, &args, NULL, NULL); |
318 | } | 318 | } |
319 | 319 | ||
320 | int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen) | ||
321 | { | ||
322 | struct rds_get_mr_for_dest_args args; | ||
323 | struct rds_get_mr_args new_args; | ||
324 | |||
325 | if (optlen != sizeof(struct rds_get_mr_for_dest_args)) | ||
326 | return -EINVAL; | ||
327 | |||
328 | if (copy_from_user(&args, (struct rds_get_mr_for_dest_args __user *)optval, | ||
329 | sizeof(struct rds_get_mr_for_dest_args))) | ||
330 | return -EFAULT; | ||
331 | |||
332 | /* | ||
333 | * Initially, just behave like get_mr(). | ||
334 | * TODO: Implement get_mr as wrapper around this | ||
335 | * and deprecate it. | ||
336 | */ | ||
337 | new_args.vec = args.vec; | ||
338 | new_args.cookie_addr = args.cookie_addr; | ||
339 | new_args.flags = args.flags; | ||
340 | |||
341 | return __rds_rdma_map(rs, &new_args, NULL, NULL); | ||
342 | } | ||
343 | |||
320 | /* | 344 | /* |
321 | * Free the MR indicated by the given R_Key | 345 | * Free the MR indicated by the given R_Key |
322 | */ | 346 | */ |
@@ -607,8 +631,8 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
607 | { | 631 | { |
608 | struct rds_rdma_op *op; | 632 | struct rds_rdma_op *op; |
609 | 633 | ||
610 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) | 634 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || |
611 | || rm->m_rdma_op != NULL) | 635 | rm->m_rdma_op != NULL) |
612 | return -EINVAL; | 636 | return -EINVAL; |
613 | 637 | ||
614 | op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); | 638 | op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); |
@@ -631,8 +655,8 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, | |||
631 | u32 r_key; | 655 | u32 r_key; |
632 | int err = 0; | 656 | int err = 0; |
633 | 657 | ||
634 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(rds_rdma_cookie_t)) | 658 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(rds_rdma_cookie_t)) || |
635 | || rm->m_rdma_cookie != 0) | 659 | rm->m_rdma_cookie != 0) |
636 | return -EINVAL; | 660 | return -EINVAL; |
637 | 661 | ||
638 | memcpy(&rm->m_rdma_cookie, CMSG_DATA(cmsg), sizeof(rm->m_rdma_cookie)); | 662 | memcpy(&rm->m_rdma_cookie, CMSG_DATA(cmsg), sizeof(rm->m_rdma_cookie)); |
@@ -668,8 +692,8 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, | |||
668 | int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, | 692 | int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, |
669 | struct cmsghdr *cmsg) | 693 | struct cmsghdr *cmsg) |
670 | { | 694 | { |
671 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_get_mr_args)) | 695 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_get_mr_args)) || |
672 | || rm->m_rdma_cookie != 0) | 696 | rm->m_rdma_cookie != 0) |
673 | return -EINVAL; | 697 | return -EINVAL; |
674 | 698 | ||
675 | return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr); | 699 | return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr); |
diff --git a/net/rds/rdma.h b/net/rds/rdma.h index 425512098b0b..909c39835a5d 100644 --- a/net/rds/rdma.h +++ b/net/rds/rdma.h | |||
@@ -61,6 +61,7 @@ static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); | 63 | int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); |
64 | int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen); | ||
64 | int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); | 65 | int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); |
65 | void rds_rdma_drop_keys(struct rds_sock *rs); | 66 | void rds_rdma_drop_keys(struct rds_sock *rs); |
66 | int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | 67 | int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, |
diff --git a/net/rds/recv.c b/net/rds/recv.c index fdff33c7b432..b426d67f760c 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -195,8 +195,8 @@ void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr, | |||
195 | * XXX we could spend more on the wire to get more robust failure | 195 | * XXX we could spend more on the wire to get more robust failure |
196 | * detection, arguably worth it to avoid data corruption. | 196 | * detection, arguably worth it to avoid data corruption. |
197 | */ | 197 | */ |
198 | if (be64_to_cpu(inc->i_hdr.h_sequence) < conn->c_next_rx_seq | 198 | if (be64_to_cpu(inc->i_hdr.h_sequence) < conn->c_next_rx_seq && |
199 | && (inc->i_hdr.h_flags & RDS_FLAG_RETRANSMITTED)) { | 199 | (inc->i_hdr.h_flags & RDS_FLAG_RETRANSMITTED)) { |
200 | rds_stats_inc(s_recv_drop_old_seq); | 200 | rds_stats_inc(s_recv_drop_old_seq); |
201 | goto out; | 201 | goto out; |
202 | } | 202 | } |
@@ -432,10 +432,9 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
432 | } | 432 | } |
433 | 433 | ||
434 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, | 434 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, |
435 | (!list_empty(&rs->rs_notify_queue) | 435 | (!list_empty(&rs->rs_notify_queue) || |
436 | || rs->rs_cong_notify | 436 | rs->rs_cong_notify || |
437 | || rds_next_incoming(rs, &inc)), | 437 | rds_next_incoming(rs, &inc)), timeo); |
438 | timeo); | ||
439 | rdsdebug("recvmsg woke inc %p timeo %ld\n", inc, | 438 | rdsdebug("recvmsg woke inc %p timeo %ld\n", inc, |
440 | timeo); | 439 | timeo); |
441 | if (timeo > 0 || timeo == MAX_SCHEDULE_TIMEOUT) | 440 | if (timeo > 0 || timeo == MAX_SCHEDULE_TIMEOUT) |
diff --git a/net/rds/send.c b/net/rds/send.c index 28c88ff3d038..b2fccfc20769 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -235,8 +235,8 @@ int rds_send_xmit(struct rds_connection *conn) | |||
235 | * connection. | 235 | * connection. |
236 | * Therefore, we never retransmit messages with RDMA ops. | 236 | * Therefore, we never retransmit messages with RDMA ops. |
237 | */ | 237 | */ |
238 | if (rm->m_rdma_op | 238 | if (rm->m_rdma_op && |
239 | && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { | 239 | test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { |
240 | spin_lock_irqsave(&conn->c_lock, flags); | 240 | spin_lock_irqsave(&conn->c_lock, flags); |
241 | if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) | 241 | if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) |
242 | list_move(&rm->m_conn_item, &to_be_dropped); | 242 | list_move(&rm->m_conn_item, &to_be_dropped); |
@@ -247,8 +247,8 @@ int rds_send_xmit(struct rds_connection *conn) | |||
247 | 247 | ||
248 | /* Require an ACK every once in a while */ | 248 | /* Require an ACK every once in a while */ |
249 | len = ntohl(rm->m_inc.i_hdr.h_len); | 249 | len = ntohl(rm->m_inc.i_hdr.h_len); |
250 | if (conn->c_unacked_packets == 0 | 250 | if (conn->c_unacked_packets == 0 || |
251 | || conn->c_unacked_bytes < len) { | 251 | conn->c_unacked_bytes < len) { |
252 | __set_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags); | 252 | __set_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags); |
253 | 253 | ||
254 | conn->c_unacked_packets = rds_sysctl_max_unacked_packets; | 254 | conn->c_unacked_packets = rds_sysctl_max_unacked_packets; |
@@ -418,8 +418,8 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) | |||
418 | spin_lock(&rm->m_rs_lock); | 418 | spin_lock(&rm->m_rs_lock); |
419 | 419 | ||
420 | ro = rm->m_rdma_op; | 420 | ro = rm->m_rdma_op; |
421 | if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) | 421 | if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && |
422 | && ro && ro->r_notify && ro->r_notifier) { | 422 | ro && ro->r_notify && ro->r_notifier) { |
423 | notifier = ro->r_notifier; | 423 | notifier = ro->r_notifier; |
424 | rs = rm->m_rs; | 424 | rs = rm->m_rs; |
425 | sock_hold(rds_rs_to_sk(rs)); | 425 | sock_hold(rds_rs_to_sk(rs)); |
@@ -549,8 +549,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) | |||
549 | list_del_init(&rm->m_sock_item); | 549 | list_del_init(&rm->m_sock_item); |
550 | rds_send_sndbuf_remove(rs, rm); | 550 | rds_send_sndbuf_remove(rs, rm); |
551 | 551 | ||
552 | if (ro && ro->r_notifier | 552 | if (ro && ro->r_notifier && (status || ro->r_notify)) { |
553 | && (status || ro->r_notify)) { | ||
554 | notifier = ro->r_notifier; | 553 | notifier = ro->r_notifier; |
555 | list_add_tail(¬ifier->n_list, | 554 | list_add_tail(¬ifier->n_list, |
556 | &rs->rs_notify_queue); | 555 | &rs->rs_notify_queue); |
@@ -877,8 +876,8 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
877 | if (ret) | 876 | if (ret) |
878 | goto out; | 877 | goto out; |
879 | 878 | ||
880 | if ((rm->m_rdma_cookie || rm->m_rdma_op) | 879 | if ((rm->m_rdma_cookie || rm->m_rdma_op) && |
881 | && conn->c_trans->xmit_rdma == NULL) { | 880 | conn->c_trans->xmit_rdma == NULL) { |
882 | if (printk_ratelimit()) | 881 | if (printk_ratelimit()) |
883 | printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", | 882 | printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", |
884 | rm->m_rdma_op, conn->c_trans->xmit_rdma); | 883 | rm->m_rdma_op, conn->c_trans->xmit_rdma); |
@@ -890,8 +889,8 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
890 | * have scheduled a delayed reconnect however - in this case | 889 | * have scheduled a delayed reconnect however - in this case |
891 | * we should not interfere. | 890 | * we should not interfere. |
892 | */ | 891 | */ |
893 | if (rds_conn_state(conn) == RDS_CONN_DOWN | 892 | if (rds_conn_state(conn) == RDS_CONN_DOWN && |
894 | && !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) | 893 | !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) |
895 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); | 894 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); |
896 | 895 | ||
897 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); | 896 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); |
@@ -973,8 +972,8 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) | |||
973 | * have scheduled a delayed reconnect however - in this case | 972 | * have scheduled a delayed reconnect however - in this case |
974 | * we should not interfere. | 973 | * we should not interfere. |
975 | */ | 974 | */ |
976 | if (rds_conn_state(conn) == RDS_CONN_DOWN | 975 | if (rds_conn_state(conn) == RDS_CONN_DOWN && |
977 | && !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) | 976 | !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) |
978 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); | 977 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); |
979 | 978 | ||
980 | ret = rds_cong_wait(conn->c_fcong, dport, 1, NULL); | 979 | ret = rds_cong_wait(conn->c_fcong, dport, 1, NULL); |
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 24b743eb0b1b..45474a436862 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -67,11 +67,11 @@ static int rds_tcp_accept_one(struct socket *sock) | |||
67 | inet = inet_sk(new_sock->sk); | 67 | inet = inet_sk(new_sock->sk); |
68 | 68 | ||
69 | rdsdebug("accepted tcp %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", | 69 | rdsdebug("accepted tcp %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", |
70 | NIPQUAD(inet->saddr), ntohs(inet->sport), | 70 | NIPQUAD(inet->inet_saddr), ntohs(inet->inet_sport), |
71 | NIPQUAD(inet->daddr), ntohs(inet->dport)); | 71 | NIPQUAD(inet->inet_daddr), ntohs(inet->inet_dport)); |
72 | 72 | ||
73 | conn = rds_conn_create(inet->saddr, inet->daddr, &rds_tcp_transport, | 73 | conn = rds_conn_create(inet->inet_saddr, inet->inet_daddr, |
74 | GFP_KERNEL); | 74 | &rds_tcp_transport, GFP_KERNEL); |
75 | if (IS_ERR(conn)) { | 75 | if (IS_ERR(conn)) { |
76 | ret = PTR_ERR(conn); | 76 | ret = PTR_ERR(conn); |
77 | goto out; | 77 | goto out; |
diff --git a/net/rds/threads.c b/net/rds/threads.c index dd7e0cad1e7c..00fa10e59af8 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c | |||
@@ -170,8 +170,8 @@ void rds_shutdown_worker(struct work_struct *work) | |||
170 | * handler is supposed to check for state DISCONNECTING | 170 | * handler is supposed to check for state DISCONNECTING |
171 | */ | 171 | */ |
172 | mutex_lock(&conn->c_cm_lock); | 172 | mutex_lock(&conn->c_cm_lock); |
173 | if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) | 173 | if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) && |
174 | && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { | 174 | !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { |
175 | rds_conn_error(conn, "shutdown called in state %d\n", | 175 | rds_conn_error(conn, "shutdown called in state %d\n", |
176 | atomic_read(&conn->c_state)); | 176 | atomic_read(&conn->c_state)); |
177 | mutex_unlock(&conn->c_cm_lock); | 177 | mutex_unlock(&conn->c_cm_lock); |