RDMA/srpt: Rework the approach for closing an RDMA channel
authorBart Van Assche <bvanassche@acm.org>
Mon, 30 Sep 2019 23:17:04 +0000 (16:17 -0700)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 4 Oct 2019 18:35:07 +0000 (15:35 -0300)
Instead of relying on a waitqueue, report when the identity of an RDMA
channel can be reused through a completion.

Link: https://lore.kernel.org/r/20190930231707.48259-13-bvanassche@acm.org
Cc: Honggang LI <honli@redhat.com>
Cc: Laurence Oberman <loberman@redhat.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/infiniband/ulp/srpt/ib_srpt.h

index dabaea3..88e11a2 100644 (file)
@@ -1928,41 +1928,22 @@ static int srpt_disconnect_ch(struct srpt_rdma_ch *ch)
        return ret;
 }
 
-static bool srpt_ch_closed(struct srpt_port *sport, struct srpt_rdma_ch *ch)
-{
-       struct srpt_nexus *nexus;
-       struct srpt_rdma_ch *ch2;
-       bool res = true;
-
-       rcu_read_lock();
-       list_for_each_entry(nexus, &sport->nexus_list, entry) {
-               list_for_each_entry(ch2, &nexus->ch_list, list) {
-                       if (ch2 == ch) {
-                               res = false;
-                               goto done;
-                       }
-               }
-       }
-done:
-       rcu_read_unlock();
-
-       return res;
-}
-
 /* Send DREQ and wait for DREP. */
 static void srpt_disconnect_ch_sync(struct srpt_rdma_ch *ch)
 {
+       DECLARE_COMPLETION_ONSTACK(closed);
        struct srpt_port *sport = ch->sport;
 
        pr_debug("ch %s-%d state %d\n", ch->sess_name, ch->qp->qp_num,
                 ch->state);
 
+       ch->closed = &closed;
+
        mutex_lock(&sport->mutex);
        srpt_disconnect_ch(ch);
        mutex_unlock(&sport->mutex);
 
-       while (wait_event_timeout(sport->ch_releaseQ, srpt_ch_closed(sport, ch),
-                                 5 * HZ) == 0)
+       while (wait_for_completion_timeout(&closed, 5 * HZ) == 0)
                pr_info("%s(%s-%d state %d): still waiting ...\n", __func__,
                        ch->sess_name, ch->qp->qp_num, ch->state);
 
@@ -2089,6 +2070,9 @@ static void srpt_release_channel_work(struct work_struct *w)
        list_del_rcu(&ch->list);
        mutex_unlock(&sport->mutex);
 
+       if (ch->closed)
+               complete(ch->closed);
+
        srpt_destroy_ch_ib(ch);
 
        srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring,
index ee9f20e..d0955bc 100644 (file)
@@ -264,6 +264,8 @@ enum rdma_ch_state {
  * @zw_cqe:       Zero-length write CQE.
  * @rcu:           RCU head.
  * @kref:         kref for this channel.
+ * @closed:       Completion object that will be signaled as soon as a new
+ *                channel object with the same identity can be created.
  * @rq_size:       IB receive queue size.
  * @max_rsp_size:  Maximum size of an RSP response message in bytes.
  * @sq_wr_avail:   number of work requests available in the send queue.
@@ -306,6 +308,7 @@ struct srpt_rdma_ch {
        struct ib_cqe           zw_cqe;
        struct rcu_head         rcu;
        struct kref             kref;
+       struct completion       *closed;
        int                     rq_size;
        u32                     max_rsp_size;
        atomic_t                sq_wr_avail;