diff options
-rw-r--r-- | net/smc/smc_core.c | 5 | ||||
-rw-r--r-- | net/smc/smc_rx.c | 29 |
2 files changed, 25 insertions, 9 deletions
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 4ca50ddf8d16..88556f0251ab 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c | |||
@@ -213,7 +213,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) | |||
213 | lgr = kzalloc(sizeof(*lgr), GFP_KERNEL); | 213 | lgr = kzalloc(sizeof(*lgr), GFP_KERNEL); |
214 | if (!lgr) { | 214 | if (!lgr) { |
215 | rc = SMC_CLC_DECL_MEM; | 215 | rc = SMC_CLC_DECL_MEM; |
216 | goto out; | 216 | goto ism_put_vlan; |
217 | } | 217 | } |
218 | lgr->is_smcd = ini->is_smcd; | 218 | lgr->is_smcd = ini->is_smcd; |
219 | lgr->sync_err = 0; | 219 | lgr->sync_err = 0; |
@@ -289,6 +289,9 @@ clear_llc_lnk: | |||
289 | smc_llc_link_clear(lnk); | 289 | smc_llc_link_clear(lnk); |
290 | free_lgr: | 290 | free_lgr: |
291 | kfree(lgr); | 291 | kfree(lgr); |
292 | ism_put_vlan: | ||
293 | if (ini->is_smcd && ini->vlan_id) | ||
294 | smc_ism_put_vlan(ini->ism_dev, ini->vlan_id); | ||
292 | out: | 295 | out: |
293 | if (rc < 0) { | 296 | if (rc < 0) { |
294 | if (rc == -ENOMEM) | 297 | if (rc == -ENOMEM) |
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c index 413a6abf227e..97e8369002d7 100644 --- a/net/smc/smc_rx.c +++ b/net/smc/smc_rx.c | |||
@@ -211,8 +211,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, | |||
211 | rc = sk_wait_event(sk, timeo, | 211 | rc = sk_wait_event(sk, timeo, |
212 | sk->sk_err || | 212 | sk->sk_err || |
213 | sk->sk_shutdown & RCV_SHUTDOWN || | 213 | sk->sk_shutdown & RCV_SHUTDOWN || |
214 | fcrit(conn) || | 214 | fcrit(conn), |
215 | smc_cdc_rxed_any_close_or_senddone(conn), | ||
216 | &wait); | 215 | &wait); |
217 | remove_wait_queue(sk_sleep(sk), &wait); | 216 | remove_wait_queue(sk_sleep(sk), &wait); |
218 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); | 217 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
@@ -262,6 +261,18 @@ static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len, | |||
262 | return -EAGAIN; | 261 | return -EAGAIN; |
263 | } | 262 | } |
264 | 263 | ||
264 | static bool smc_rx_recvmsg_data_available(struct smc_sock *smc) | ||
265 | { | ||
266 | struct smc_connection *conn = &smc->conn; | ||
267 | |||
268 | if (smc_rx_data_available(conn)) | ||
269 | return true; | ||
270 | else if (conn->urg_state == SMC_URG_VALID) | ||
271 | /* we received a single urgent Byte - skip */ | ||
272 | smc_rx_update_cons(smc, 0); | ||
273 | return false; | ||
274 | } | ||
275 | |||
265 | /* smc_rx_recvmsg - receive data from RMBE | 276 | /* smc_rx_recvmsg - receive data from RMBE |
266 | * @msg: copy data to receive buffer | 277 | * @msg: copy data to receive buffer |
267 | * @pipe: copy data to pipe if set - indicates splice() call | 278 | * @pipe: copy data to pipe if set - indicates splice() call |
@@ -303,16 +314,18 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, | |||
303 | if (read_done >= target || (pipe && read_done)) | 314 | if (read_done >= target || (pipe && read_done)) |
304 | break; | 315 | break; |
305 | 316 | ||
306 | if (atomic_read(&conn->bytes_to_rcv)) | 317 | if (smc_rx_recvmsg_data_available(smc)) |
307 | goto copy; | 318 | goto copy; |
308 | else if (conn->urg_state == SMC_URG_VALID) | ||
309 | /* we received a single urgent Byte - skip */ | ||
310 | smc_rx_update_cons(smc, 0); | ||
311 | 319 | ||
312 | if (sk->sk_shutdown & RCV_SHUTDOWN || | 320 | if (sk->sk_shutdown & RCV_SHUTDOWN || |
313 | smc_cdc_rxed_any_close_or_senddone(conn) || | 321 | conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) { |
314 | conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) | 322 | /* smc_cdc_msg_recv_action() could have run after |
323 | * above smc_rx_recvmsg_data_available() | ||
324 | */ | ||
325 | if (smc_rx_recvmsg_data_available(smc)) | ||
326 | goto copy; | ||
315 | break; | 327 | break; |
328 | } | ||
316 | 329 | ||
317 | if (read_done) { | 330 | if (read_done) { |
318 | if (sk->sk_err || | 331 | if (sk->sk_err || |