Merge branch 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[linux-2.6-microblaze.git] / net / smc / smc_tx.c
index fea6482..838bce2 100644 (file)
@@ -248,8 +248,10 @@ static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset,
                peer_rmbe_offset;
        rdma_wr.rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey;
        rc = ib_post_send(link->roce_qp, &rdma_wr.wr, &failed_wr);
-       if (rc)
+       if (rc) {
                conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
+               smc_lgr_terminate(lgr);
+       }
        return rc;
 }
 
@@ -406,8 +408,9 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
                                goto out_unlock;
                        }
                        rc = 0;
-                       schedule_delayed_work(&conn->tx_work,
-                                             SMC_TX_WORK_DELAY);
+                       if (conn->alert_token_local) /* connection healthy */
+                               schedule_delayed_work(&conn->tx_work,
+                                                     SMC_TX_WORK_DELAY);
                }
                goto out_unlock;
        }
@@ -438,10 +441,17 @@ static void smc_tx_work(struct work_struct *work)
        int rc;
 
        lock_sock(&smc->sk);
+       if (smc->sk.sk_err ||
+           !conn->alert_token_local ||
+           conn->local_rx_ctrl.conn_state_flags.peer_conn_abort)
+               goto out;
+
        rc = smc_tx_sndbuf_nonempty(conn);
        if (!rc && conn->local_rx_ctrl.prod_flags.write_blocked &&
            !atomic_read(&conn->bytes_to_rcv))
                conn->local_rx_ctrl.prod_flags.write_blocked = 0;
+
+out:
        release_sock(&smc->sk);
 }
 
@@ -462,7 +472,8 @@ void smc_tx_consumer_update(struct smc_connection *conn)
            ((to_confirm > conn->rmbe_update_limit) &&
             ((to_confirm > (conn->rmbe_size / 2)) ||
              conn->local_rx_ctrl.prod_flags.write_blocked))) {
-               if (smc_cdc_get_slot_and_msg_send(conn) < 0) {
+               if ((smc_cdc_get_slot_and_msg_send(conn) < 0) &&
+                   conn->alert_token_local) { /* connection healthy */
                        schedule_delayed_work(&conn->tx_work,
                                              SMC_TX_WORK_DELAY);
                        return;