Merge tag 'v5.2-rc6' into sched/core, to refresh the branch
[linux-2.6-block.git] / drivers / infiniband / hw / hfi1 / sdma.c
index b0110728f5418bb158b2af2ca0c7e440d24c3274..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));
 }
 
 /*
@@ -855,14 +869,13 @@ struct sdma_engine *sdma_select_user_engine(struct hfi1_devdata *dd,
 {
        struct sdma_rht_node *rht_node;
        struct sdma_engine *sde = NULL;
-       const struct cpumask *current_mask = &current->cpus_allowed;
        unsigned long cpu_id;
 
        /*
         * To ensure that always the same sdma engine(s) will be
         * selected make sure the process is pinned to this CPU only.
         */
-       if (cpumask_weight(current_mask) != 1)
+       if (current->nr_cpus_allowed != 1)
                goto out;
 
        cpu_id = smp_processor_id();
@@ -2413,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:
@@ -2511,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: