diff options
Diffstat (limited to 'net/rds/loop.c')
-rw-r--r-- | net/rds/loop.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/net/rds/loop.c b/net/rds/loop.c index dd9879379457..c390156b426f 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c | |||
@@ -61,10 +61,17 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
61 | unsigned int hdr_off, unsigned int sg, | 61 | unsigned int hdr_off, unsigned int sg, |
62 | unsigned int off) | 62 | unsigned int off) |
63 | { | 63 | { |
64 | /* Do not send cong updates to loopback */ | ||
65 | if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { | ||
66 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); | ||
67 | return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; | ||
68 | } | ||
69 | |||
64 | BUG_ON(hdr_off || sg || off); | 70 | BUG_ON(hdr_off || sg || off); |
65 | 71 | ||
66 | rds_inc_init(&rm->m_inc, conn, conn->c_laddr); | 72 | rds_inc_init(&rm->m_inc, conn, conn->c_laddr); |
67 | rds_message_addref(rm); /* for the inc */ | 73 | /* For the embedded inc. Matching put is in loop_inc_free() */ |
74 | rds_message_addref(rm); | ||
68 | 75 | ||
69 | rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc, | 76 | rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc, |
70 | GFP_KERNEL, KM_USER0); | 77 | GFP_KERNEL, KM_USER0); |
@@ -77,16 +84,14 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
77 | return sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len); | 84 | return sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len); |
78 | } | 85 | } |
79 | 86 | ||
80 | static int rds_loop_xmit_cong_map(struct rds_connection *conn, | 87 | /* |
81 | struct rds_cong_map *map, | 88 | * See rds_loop_xmit(). Since our inc is embedded in the rm, we |
82 | unsigned long offset) | 89 | * make sure the rm lives at least until the inc is done. |
90 | */ | ||
91 | static void rds_loop_inc_free(struct rds_incoming *inc) | ||
83 | { | 92 | { |
84 | BUG_ON(offset); | 93 | struct rds_message *rm = container_of(inc, struct rds_message, m_inc); |
85 | BUG_ON(map != conn->c_lcong); | 94 | rds_message_put(rm); |
86 | |||
87 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); | ||
88 | |||
89 | return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; | ||
90 | } | 95 | } |
91 | 96 | ||
92 | /* we need to at least give the thread something to succeed */ | 97 | /* we need to at least give the thread something to succeed */ |
@@ -112,7 +117,7 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
112 | unsigned long flags; | 117 | unsigned long flags; |
113 | 118 | ||
114 | lc = kzalloc(sizeof(struct rds_loop_connection), GFP_KERNEL); | 119 | lc = kzalloc(sizeof(struct rds_loop_connection), GFP_KERNEL); |
115 | if (lc == NULL) | 120 | if (!lc) |
116 | return -ENOMEM; | 121 | return -ENOMEM; |
117 | 122 | ||
118 | INIT_LIST_HEAD(&lc->loop_node); | 123 | INIT_LIST_HEAD(&lc->loop_node); |
@@ -169,14 +174,12 @@ void rds_loop_exit(void) | |||
169 | */ | 174 | */ |
170 | struct rds_transport rds_loop_transport = { | 175 | struct rds_transport rds_loop_transport = { |
171 | .xmit = rds_loop_xmit, | 176 | .xmit = rds_loop_xmit, |
172 | .xmit_cong_map = rds_loop_xmit_cong_map, | ||
173 | .recv = rds_loop_recv, | 177 | .recv = rds_loop_recv, |
174 | .conn_alloc = rds_loop_conn_alloc, | 178 | .conn_alloc = rds_loop_conn_alloc, |
175 | .conn_free = rds_loop_conn_free, | 179 | .conn_free = rds_loop_conn_free, |
176 | .conn_connect = rds_loop_conn_connect, | 180 | .conn_connect = rds_loop_conn_connect, |
177 | .conn_shutdown = rds_loop_conn_shutdown, | 181 | .conn_shutdown = rds_loop_conn_shutdown, |
178 | .inc_copy_to_user = rds_message_inc_copy_to_user, | 182 | .inc_copy_to_user = rds_message_inc_copy_to_user, |
179 | .inc_purge = rds_message_inc_purge, | 183 | .inc_free = rds_loop_inc_free, |
180 | .inc_free = rds_message_inc_free, | ||
181 | .t_name = "loopback", | 184 | .t_name = "loopback", |
182 | }; | 185 | }; |