diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2010-11-17 12:24:19 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-10 05:35:01 -0500 |
commit | 8869d683b7491467fd39fcbe79756fce3e6f35e7 (patch) | |
tree | b8634a30967f36ff34f4de8ecf38eb96997f5f28 /drivers/block | |
parent | 127b317844e7cc0458743b604998bece95eab030 (diff) |
drbd: Fixed inc_ap_bio()
The condition must be checked after perpare_to_wait(). The old
implementaion could loose wakeup events. Never observed in real
life.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 77ac6765fd57..9a944604939f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -2309,15 +2309,21 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) | |||
2309 | return 1; | 2309 | return 1; |
2310 | } | 2310 | } |
2311 | 2311 | ||
2312 | /* I'd like to use wait_event_lock_irq, | 2312 | static inline int _inc_ap_bio_cond(struct drbd_conf *mdev, int count) |
2313 | * but I'm not sure when it got introduced, | ||
2314 | * and not sure when it has 3 or 4 arguments */ | ||
2315 | static inline void inc_ap_bio(struct drbd_conf *mdev, int count) | ||
2316 | { | 2313 | { |
2317 | /* compare with after_state_ch, | 2314 | int rv = 0; |
2318 | * os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S */ | 2315 | |
2319 | DEFINE_WAIT(wait); | 2316 | spin_lock_irq(&mdev->req_lock); |
2317 | rv = __inc_ap_bio_cond(mdev); | ||
2318 | if (rv) | ||
2319 | atomic_add(count, &mdev->ap_bio_cnt); | ||
2320 | spin_unlock_irq(&mdev->req_lock); | ||
2321 | |||
2322 | return rv; | ||
2323 | } | ||
2320 | 2324 | ||
2325 | static inline void inc_ap_bio(struct drbd_conf *mdev, int count) | ||
2326 | { | ||
2321 | /* we wait here | 2327 | /* we wait here |
2322 | * as long as the device is suspended | 2328 | * as long as the device is suspended |
2323 | * until the bitmap is no longer on the fly during connection | 2329 | * until the bitmap is no longer on the fly during connection |
@@ -2326,16 +2332,7 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int count) | |||
2326 | * to avoid races with the reconnect code, | 2332 | * to avoid races with the reconnect code, |
2327 | * we need to atomic_inc within the spinlock. */ | 2333 | * we need to atomic_inc within the spinlock. */ |
2328 | 2334 | ||
2329 | spin_lock_irq(&mdev->req_lock); | 2335 | wait_event(mdev->misc_wait, _inc_ap_bio_cond(mdev, count)); |
2330 | while (!__inc_ap_bio_cond(mdev)) { | ||
2331 | prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); | ||
2332 | spin_unlock_irq(&mdev->req_lock); | ||
2333 | schedule(); | ||
2334 | finish_wait(&mdev->misc_wait, &wait); | ||
2335 | spin_lock_irq(&mdev->req_lock); | ||
2336 | } | ||
2337 | atomic_add(count, &mdev->ap_bio_cnt); | ||
2338 | spin_unlock_irq(&mdev->req_lock); | ||
2339 | } | 2336 | } |
2340 | 2337 | ||
2341 | static inline void dec_ap_bio(struct drbd_conf *mdev) | 2338 | static inline void dec_ap_bio(struct drbd_conf *mdev) |