drbd: use test_and_set_bit() to decide if bm_io_work should be queued
authorPhilipp Reisner <philipp.reisner@linbit.com>
Tue, 16 Nov 2010 09:07:53 +0000 (10:07 +0100)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 10 Mar 2011 10:34:59 +0000 (11:34 +0100)
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_main.c

index f49505cf8d0f47560dc7583c6ab24b209c2f067c..843b909669200f8b17ad9b65b918a85a50fda416 100644 (file)
@@ -3772,6 +3772,7 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
        drbd_bm_unlock(mdev);
 
        clear_bit(BITMAP_IO, &mdev->flags);
+       smp_mb__after_clear_bit();
        wake_up(&mdev->misc_wait);
 
        if (work->done)
@@ -3850,11 +3851,8 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev,
 
        set_bit(BITMAP_IO, &mdev->flags);
        if (atomic_read(&mdev->ap_bio_cnt) == 0) {
-               if (list_empty(&mdev->bm_io_work.w.list)) {
-                       set_bit(BITMAP_IO_QUEUED, &mdev->flags);
+               if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags))
                        drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w);
-               } else
-                       dev_err(DEV, "FIXME avoided double queuing bm_io_work\n");
        }
 }