Merge tag 'thermal-v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/therma...
[linux-2.6-microblaze.git] / net / smc / smc_tx.c
index 9f1ade8..4532c16 100644 (file)
@@ -228,8 +228,8 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len)
                        /* for a corked socket defer the RDMA writes if there
                         * is still sufficient sndbuf_space available
                         */
-                       schedule_delayed_work(&conn->tx_work,
-                                             SMC_TX_CORK_DELAY);
+                       queue_delayed_work(conn->lgr->tx_wq, &conn->tx_work,
+                                          SMC_TX_CORK_DELAY);
                else
                        smc_tx_sndbuf_nonempty(conn);
        } /* while (msg_data_left(msg)) */
@@ -269,22 +269,21 @@ static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset,
                             int num_sges, struct ib_rdma_wr *rdma_wr)
 {
        struct smc_link_group *lgr = conn->lgr;
-       struct smc_link *link;
+       struct smc_link *link = conn->lnk;
        int rc;
 
-       link = &lgr->lnk[SMC_SINGLE_LINK];
        rdma_wr->wr.wr_id = smc_wr_tx_get_next_wr_id(link);
        rdma_wr->wr.num_sge = num_sges;
        rdma_wr->remote_addr =
-               lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr +
+               lgr->rtokens[conn->rtoken_idx][link->link_idx].dma_addr +
                /* RMBE within RMB */
                conn->tx_off +
                /* offset within RMBE */
                peer_rmbe_offset;
-       rdma_wr->rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey;
+       rdma_wr->rkey = lgr->rtokens[conn->rtoken_idx][link->link_idx].rkey;
        rc = ib_post_send(link->roce_qp, &rdma_wr->wr, NULL);
        if (rc)
-               smc_lgr_terminate_sched(lgr);
+               smcr_link_down_cond_sched(link);
        return rc;
 }
 
@@ -310,8 +309,10 @@ static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len,
                               size_t dst_off, size_t dst_len,
                               struct smc_rdma_wr *wr_rdma_buf)
 {
+       struct smc_link *link = conn->lnk;
+
        dma_addr_t dma_addr =
-               sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl);
+               sg_dma_address(conn->sndbuf_desc->sgt[link->link_idx].sgl);
        int src_len_sum = src_len, dst_len_sum = dst_len;
        int sent_count = src_off;
        int srcchunk, dstchunk;
@@ -481,12 +482,13 @@ static int smc_tx_rdma_writes(struct smc_connection *conn,
 static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
 {
        struct smc_cdc_producer_flags *pflags = &conn->local_tx_ctrl.prod_flags;
+       struct smc_link *link = conn->lnk;
        struct smc_rdma_wr *wr_rdma_buf;
        struct smc_cdc_tx_pend *pend;
        struct smc_wr_buf *wr_buf;
        int rc;
 
-       rc = smc_cdc_get_free_slot(conn, &wr_buf, &wr_rdma_buf, &pend);
+       rc = smc_cdc_get_free_slot(conn, link, &wr_buf, &wr_rdma_buf, &pend);
        if (rc < 0) {
                if (rc == -EBUSY) {
                        struct smc_sock *smc =
@@ -497,17 +499,24 @@ static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
                        if (conn->killed)
                                return -EPIPE;
                        rc = 0;
-                       mod_delayed_work(system_wq, &conn->tx_work,
+                       mod_delayed_work(conn->lgr->tx_wq, &conn->tx_work,
                                         SMC_TX_WORK_DELAY);
                }
                return rc;
        }
 
        spin_lock_bh(&conn->send_lock);
+       if (link != conn->lnk) {
+               /* link of connection changed, tx_work will restart */
+               smc_wr_tx_put_slot(link,
+                                  (struct smc_wr_tx_pend_priv *)pend);
+               rc = -ENOLINK;
+               goto out_unlock;
+       }
        if (!pflags->urg_data_present) {
                rc = smc_tx_rdma_writes(conn, wr_rdma_buf);
                if (rc) {
-                       smc_wr_tx_put_slot(&conn->lgr->lnk[SMC_SINGLE_LINK],
+                       smc_wr_tx_put_slot(link,
                                           (struct smc_wr_tx_pend_priv *)pend);
                        goto out_unlock;
                }
@@ -614,8 +623,8 @@ void smc_tx_consumer_update(struct smc_connection *conn, bool force)
                        return;
                if ((smc_cdc_get_slot_and_msg_send(conn) < 0) &&
                    !conn->killed) {
-                       schedule_delayed_work(&conn->tx_work,
-                                             SMC_TX_WORK_DELAY);
+                       queue_delayed_work(conn->lgr->tx_wq, &conn->tx_work,
+                                          SMC_TX_WORK_DELAY);
                        return;
                }
        }