md/raid1,raid10: fix deadlock with freeze_array()
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / md / raid10.c
index c9acbd7..8d925dc 100644 (file)
@@ -952,7 +952,7 @@ static void raise_barrier(struct r10conf *conf, int force)
 
        /* Wait until no block IO is waiting (unless 'force') */
        wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting,
-                           conf->resync_lock);
+                           conf->resync_lock);
 
        /* block any new IO from starting */
        conf->barrier++;
@@ -960,7 +960,7 @@ static void raise_barrier(struct r10conf *conf, int force)
        /* Now wait for all pending IO to complete */
        wait_event_lock_irq(conf->wait_barrier,
                            !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
-                           conf->resync_lock);
+                           conf->resync_lock);
 
        spin_unlock_irq(&conf->resync_lock);
 }
@@ -993,8 +993,7 @@ static void wait_barrier(struct r10conf *conf)
                                    (conf->nr_pending &&
                                     current->bio_list &&
                                     !bio_list_empty(current->bio_list)),
-                                   conf->resync_lock,
-                       );
+                                   conf->resync_lock);
                conf->nr_waiting--;
        }
        conf->nr_pending++;
@@ -1027,10 +1026,10 @@ static void freeze_array(struct r10conf *conf)
        spin_lock_irq(&conf->resync_lock);
        conf->barrier++;
        conf->nr_waiting++;
-       wait_event_lock_irq(conf->wait_barrier,
-                           conf->nr_pending == conf->nr_queued+1,
-                           conf->resync_lock,
-                           flush_pending_writes(conf));
+       wait_event_lock_irq_cmd(conf->wait_barrier,
+                               conf->nr_pending == conf->nr_queued+1,
+                               conf->resync_lock,
+                               flush_pending_writes(conf));
 
        spin_unlock_irq(&conf->resync_lock);
 }
@@ -1074,6 +1073,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
                spin_unlock_irq(&conf->device_lock);
+               wake_up(&conf->wait_barrier);
                md_wakeup_thread(mddev->thread);
                kfree(plug);
                return;