Merge tag 'icc-6.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc...
[linux-2.6-microblaze.git] / drivers / infiniband / ulp / rtrs / rtrs-srv.c
index 75e5660..1d33efb 100644 (file)
@@ -65,8 +65,9 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path,
 {
        enum rtrs_srv_state old_state;
        bool changed = false;
+       unsigned long flags;
 
-       spin_lock_irq(&srv_path->state_lock);
+       spin_lock_irqsave(&srv_path->state_lock, flags);
        old_state = srv_path->state;
        switch (new_state) {
        case RTRS_SRV_CONNECTED:
@@ -87,7 +88,7 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path,
        }
        if (changed)
                srv_path->state = new_state;
-       spin_unlock_irq(&srv_path->state_lock);
+       spin_unlock_irqrestore(&srv_path->state_lock, flags);
 
        return changed;
 }
@@ -550,7 +551,10 @@ static void unmap_cont_bufs(struct rtrs_srv_path *srv_path)
                struct rtrs_srv_mr *srv_mr;
 
                srv_mr = &srv_path->mrs[i];
-               rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1);
+
+               if (always_invalidate)
+                       rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1);
+
                ib_dereg_mr(srv_mr->mr);
                ib_dma_unmap_sg(srv_path->s.dev->ib_dev, srv_mr->sgt.sgl,
                                srv_mr->sgt.nents, DMA_BIDIRECTIONAL);
@@ -709,20 +713,23 @@ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
        WARN_ON(wc->opcode != IB_WC_SEND);
 }
 
-static void rtrs_srv_path_up(struct rtrs_srv_path *srv_path)
+static int rtrs_srv_path_up(struct rtrs_srv_path *srv_path)
 {
        struct rtrs_srv_sess *srv = srv_path->srv;
        struct rtrs_srv_ctx *ctx = srv->ctx;
-       int up;
+       int up, ret = 0;
 
        mutex_lock(&srv->paths_ev_mutex);
        up = ++srv->paths_up;
        if (up == 1)
-               ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL);
+               ret = ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL);
        mutex_unlock(&srv->paths_ev_mutex);
 
        /* Mark session as established */
-       srv_path->established = true;
+       if (!ret)
+               srv_path->established = true;
+
+       return ret;
 }
 
 static void rtrs_srv_path_down(struct rtrs_srv_path *srv_path)
@@ -851,7 +858,12 @@ static int process_info_req(struct rtrs_srv_con *con,
                goto iu_free;
        kobject_get(&srv_path->kobj);
        get_device(&srv_path->srv->dev);
-       rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED);
+       err = rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED);
+       if (!err) {
+               rtrs_err(s, "rtrs_srv_change_state(), err: %d\n", err);
+               goto iu_free;
+       }
+
        rtrs_srv_start_hb(srv_path);
 
        /*
@@ -860,7 +872,11 @@ static int process_info_req(struct rtrs_srv_con *con,
         * all connections are successfully established.  Thus, simply notify
         * listener with a proper event if we are the first path.
         */
-       rtrs_srv_path_up(srv_path);
+       err = rtrs_srv_path_up(srv_path);
+       if (err) {
+               rtrs_err(s, "rtrs_srv_path_up(), err: %d\n", err);
+               goto iu_free;
+       }
 
        ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
                                      tx_iu->dma_addr,
@@ -1516,7 +1532,6 @@ static void rtrs_srv_close_work(struct work_struct *work)
 
        srv_path = container_of(work, typeof(*srv_path), close_work);
 
-       rtrs_srv_destroy_path_files(srv_path);
        rtrs_srv_stop_hb(srv_path);
 
        for (i = 0; i < srv_path->s.con_num; i++) {
@@ -1536,6 +1551,8 @@ static void rtrs_srv_close_work(struct work_struct *work)
        /* Wait for all completion */
        wait_for_completion(&srv_path->complete_done);
 
+       rtrs_srv_destroy_path_files(srv_path);
+
        /* Notify upper layer if we are the last path */
        rtrs_srv_path_down(srv_path);