net/smc: make wait for work request uninterruptible
authorUrsula Braun <ubraun@linux.vnet.ibm.com>
Wed, 24 Jan 2018 09:28:15 +0000 (10:28 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Jan 2018 15:52:57 +0000 (10:52 -0500)
Work requests are needed for every ib_post_send(), among them the
ib_post_send() to signal closing. If an smc socket program is cancelled,
the smc connections should be cleaned up, and require sending of closing
signals to the peer. This may fail, if a wait for
a free work request is needed, but is cancelled immediately due to the
cancel interrupt. To guarantee notification of the peer, the wait for
a work request is changed to uninterruptible.

And the area to receive work request completion info with
ib_poll_cq() is cleared first.
And _tx_ variable names are used in the _tx_routines for the
demultiplexing common type in the header.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc_wr.c

index a4477b4a9c180d786a3ce3eabb88a3cd9eabf74e..5ed94109d1d6fdb951f6d392378bc7beabd8ab53 100644 (file)
@@ -122,6 +122,7 @@ static void smc_wr_tx_tasklet_fn(unsigned long data)
 again:
        polled++;
        do {
+               memset(&wc, 0, sizeof(wc));
                rc = ib_poll_cq(dev->roce_cq_send, SMC_WR_MAX_POLL_CQE, wc);
                if (polled == 1) {
                        ib_req_notify_cq(dev->roce_cq_send,
@@ -185,7 +186,7 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
                if (rc)
                        return rc;
        } else {
-               rc = wait_event_interruptible_timeout(
+               rc = wait_event_timeout(
                        link->wr_tx_wait,
                        (smc_wr_tx_get_free_slot_index(link, &idx) != -EBUSY),
                        SMC_WR_TX_WAIT_FREE_SLOT_TIME);
@@ -198,8 +199,6 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
                        smc_lgr_terminate(lgr);
                        return -EPIPE;
                }
-               if (rc == -ERESTARTSYS)
-                       return -EINTR;
                if (idx == link->wr_tx_cnt)
                        return -EPIPE;
        }
@@ -300,18 +299,18 @@ int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr)
        return rc;
 }
 
-void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_rx_hdr_type,
+void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_tx_hdr_type,
                             smc_wr_tx_filter filter,
                             smc_wr_tx_dismisser dismisser,
                             unsigned long data)
 {
        struct smc_wr_tx_pend_priv *tx_pend;
-       struct smc_wr_rx_hdr *wr_rx;
+       struct smc_wr_rx_hdr *wr_tx;
        int i;
 
        for_each_set_bit(i, link->wr_tx_mask, link->wr_tx_cnt) {
-               wr_rx = (struct smc_wr_rx_hdr *)&link->wr_rx_bufs[i];
-               if (wr_rx->type != wr_rx_hdr_type)
+               wr_tx = (struct smc_wr_rx_hdr *)&link->wr_tx_bufs[i];
+               if (wr_tx->type != wr_tx_hdr_type)
                        continue;
                tx_pend = &link->wr_tx_pends[i].priv;
                if (filter(tx_pend, data))