aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2012-11-30 05:42:40 -0500
committerJens Axboe <axboe@kernel.dk>2012-11-30 05:47:57 -0500
commiteed8c02e680c04cd737e0a9cef74e68d8eb0cefa (patch)
tree8bd2bd10b0c02bb8a579ca3fd4f1482e5335c747 /drivers/md/raid10.c
parentd33b98fc82b0908e91fb05ae081acaed7323f9d2 (diff)
wait: add wait_event_lock_irq() interface
New wait_event{_interruptible}_lock_irq{_cmd} macros added. This commit moves the private wait_event_lock_irq() macro from MD to regular wait includes, introduces new macro wait_event_lock_irq_cmd() instead of using the old method with omitting cmd parameter which is ugly and makes a use of new macros in the MD. It also introduces the _interruptible_ variant. The use of new interface is when one have a special lock to protect data structures used in the condition, or one also needs to invoke "cmd" before putting it to sleep. All new macros are expected to be called with the lock taken. The lock is released before sleep and is reacquired afterwards. We will leave the macro with the lock held. Note to DM: IMO this should also fix theoretical race on waitqueue while using simultaneously wait_event_lock_irq() and wait_event() because of lack of locking around current state setting and wait queue removal. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Cc: Neil Brown <neilb@suse.de> Cc: David Howells <dhowells@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 906ccbd0f7dc..9a08f621b27d 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -952,7 +952,7 @@ static void raise_barrier(struct r10conf *conf, int force)
952 952
953 /* Wait until no block IO is waiting (unless 'force') */ 953 /* Wait until no block IO is waiting (unless 'force') */
954 wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, 954 wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting,
955 conf->resync_lock, ); 955 conf->resync_lock);
956 956
957 /* block any new IO from starting */ 957 /* block any new IO from starting */
958 conf->barrier++; 958 conf->barrier++;
@@ -960,7 +960,7 @@ static void raise_barrier(struct r10conf *conf, int force)
960 /* Now wait for all pending IO to complete */ 960 /* Now wait for all pending IO to complete */
961 wait_event_lock_irq(conf->wait_barrier, 961 wait_event_lock_irq(conf->wait_barrier,
962 !conf->nr_pending && conf->barrier < RESYNC_DEPTH, 962 !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
963 conf->resync_lock, ); 963 conf->resync_lock);
964 964
965 spin_unlock_irq(&conf->resync_lock); 965 spin_unlock_irq(&conf->resync_lock);
966} 966}
@@ -993,8 +993,7 @@ static void wait_barrier(struct r10conf *conf)
993 (conf->nr_pending && 993 (conf->nr_pending &&
994 current->bio_list && 994 current->bio_list &&
995 !bio_list_empty(current->bio_list)), 995 !bio_list_empty(current->bio_list)),
996 conf->resync_lock, 996 conf->resync_lock);
997 );
998 conf->nr_waiting--; 997 conf->nr_waiting--;
999 } 998 }
1000 conf->nr_pending++; 999 conf->nr_pending++;
@@ -1027,10 +1026,10 @@ static void freeze_array(struct r10conf *conf)
1027 spin_lock_irq(&conf->resync_lock); 1026 spin_lock_irq(&conf->resync_lock);
1028 conf->barrier++; 1027 conf->barrier++;
1029 conf->nr_waiting++; 1028 conf->nr_waiting++;
1030 wait_event_lock_irq(conf->wait_barrier, 1029 wait_event_lock_irq_cmd(conf->wait_barrier,
1031 conf->nr_pending == conf->nr_queued+1, 1030 conf->nr_pending == conf->nr_queued+1,
1032 conf->resync_lock, 1031 conf->resync_lock,
1033 flush_pending_writes(conf)); 1032 flush_pending_writes(conf));
1034 1033
1035 spin_unlock_irq(&conf->resync_lock); 1034 spin_unlock_irq(&conf->resync_lock);
1036} 1035}