Merge tag 'v5.2-rc6' into sched/core, to refresh the branch
[linux-2.6-block.git] / drivers / infiniband / hw / hfi1 / sdma.c
index 7e8139ee0cc1bdcaf49971b6b926d3cea045afbf..2395fd4233a7e729041b2f31fb8639c996fa70ed 100644 (file)
@@ -405,19 +405,33 @@ static void sdma_flush(struct sdma_engine *sde)
        struct sdma_txreq *txp, *txp_next;
        LIST_HEAD(flushlist);
        unsigned long flags;
+       uint seq;
 
        /* flush from head to tail */
        sdma_flush_descq(sde);
        spin_lock_irqsave(&sde->flushlist_lock, flags);
        /* copy flush list */
-       list_for_each_entry_safe(txp, txp_next, &sde->flushlist, list) {
-               list_del_init(&txp->list);
-               list_add_tail(&txp->list, &flushlist);
-       }
+       list_splice_init(&sde->flushlist, &flushlist);
        spin_unlock_irqrestore(&sde->flushlist_lock, flags);
        /* flush from flush list */
        list_for_each_entry_safe(txp, txp_next, &flushlist, list)
                complete_tx(sde, txp, SDMA_TXREQ_S_ABORTED);
+       /* wakeup QPs orphaned on the dmawait list */
+       do {
+               struct iowait *w, *nw;
+
+               seq = read_seqbegin(&sde->waitlock);
+               if (!list_empty(&sde->dmawait)) {
+                       write_seqlock(&sde->waitlock);
+                       list_for_each_entry_safe(w, nw, &sde->dmawait, list) {
+                               if (w->wakeup) {
+                                       w->wakeup(w, SDMA_AVAIL_REASON);
+                                       list_del_init(&w->list);
+                               }
+                       }
+                       write_sequnlock(&sde->waitlock);
+               }
+       } while (read_seqretry(&sde->waitlock, seq));
 }
 
 /*
@@ -2412,7 +2426,7 @@ unlock_noconn:
        list_add_tail(&tx->list, &sde->flushlist);
        spin_unlock(&sde->flushlist_lock);
        iowait_inc_wait_count(wait, tx->num_desc);
-       schedule_work(&sde->flush_worker);
+       queue_work_on(sde->cpu, system_highpri_wq, &sde->flush_worker);
        ret = -ECOMM;
        goto unlock;
 nodesc:
@@ -2510,7 +2524,7 @@ unlock_noconn:
                iowait_inc_wait_count(wait, tx->num_desc);
        }
        spin_unlock(&sde->flushlist_lock);
-       schedule_work(&sde->flush_worker);
+       queue_work_on(sde->cpu, system_highpri_wq, &sde->flush_worker);
        ret = -ECOMM;
        goto update_tail;
 nodesc: