diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2011-01-14 10:03:11 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-10 05:45:36 -0500 |
commit | 370a43e7982dd497822097e0ae6022947ac2e7d4 (patch) | |
tree | a501836af9959177a1ef9b6746ab21c3b3af6d94 /drivers/block/drbd | |
parent | 71c78cfba232de8f61a4b1bbb6e876424d133407 (diff) |
drbd: Work on the Ahead -> SyncSource transition
The test if rs_pending_cnt == 0 was too weak. Using Test for
unacked_cnt == 0 instead. Moved that into the worker.
Since unacked_cnt gets already increased when an P_RS_DATA_REQ
comes in.
Also using a timer to make Ahead -> SyncSource -> Ahead cycles
slower...
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 3 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 4 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 8 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 16 |
4 files changed, 25 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 3c8eecd9666d..cfe7fff459e3 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -850,6 +850,7 @@ enum { | |||
850 | GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ | 850 | GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ |
851 | NEW_CUR_UUID, /* Create new current UUID when thawing IO */ | 851 | NEW_CUR_UUID, /* Create new current UUID when thawing IO */ |
852 | AL_SUSPENDED, /* Activity logging is currently suspended. */ | 852 | AL_SUSPENDED, /* Activity logging is currently suspended. */ |
853 | AHEAD_TO_SYNC_SOURCE, /* Ahead -> SyncSource queued */ | ||
853 | }; | 854 | }; |
854 | 855 | ||
855 | struct drbd_bitmap; /* opaque for drbd_conf */ | 856 | struct drbd_bitmap; /* opaque for drbd_conf */ |
@@ -961,6 +962,7 @@ struct drbd_conf { | |||
961 | start_resync_work; | 962 | start_resync_work; |
962 | struct timer_list resync_timer; | 963 | struct timer_list resync_timer; |
963 | struct timer_list md_sync_timer; | 964 | struct timer_list md_sync_timer; |
965 | struct timer_list start_resync_timer; | ||
964 | #ifdef DRBD_DEBUG_MD_SYNC | 966 | #ifdef DRBD_DEBUG_MD_SYNC |
965 | struct { | 967 | struct { |
966 | unsigned int line; | 968 | unsigned int line; |
@@ -1544,6 +1546,7 @@ extern int w_send_oos(struct drbd_conf *, struct drbd_work *, int); | |||
1544 | extern int w_start_resync(struct drbd_conf *, struct drbd_work *, int); | 1546 | extern int w_start_resync(struct drbd_conf *, struct drbd_work *, int); |
1545 | 1547 | ||
1546 | extern void resync_timer_fn(unsigned long data); | 1548 | extern void resync_timer_fn(unsigned long data); |
1549 | extern void start_resync_timer_fn(unsigned long data); | ||
1547 | 1550 | ||
1548 | /* drbd_receiver.c */ | 1551 | /* drbd_receiver.c */ |
1549 | extern int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector); | 1552 | extern int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector); |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index b3b6d3190f65..8ec7c65988be 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2984,12 +2984,16 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2984 | mdev->go_diskless.cb = w_go_diskless; | 2984 | mdev->go_diskless.cb = w_go_diskless; |
2985 | mdev->md_sync_work.cb = w_md_sync; | 2985 | mdev->md_sync_work.cb = w_md_sync; |
2986 | mdev->bm_io_work.w.cb = w_bitmap_io; | 2986 | mdev->bm_io_work.w.cb = w_bitmap_io; |
2987 | mdev->start_resync_work.cb = w_start_resync; | ||
2987 | init_timer(&mdev->resync_timer); | 2988 | init_timer(&mdev->resync_timer); |
2988 | init_timer(&mdev->md_sync_timer); | 2989 | init_timer(&mdev->md_sync_timer); |
2990 | init_timer(&mdev->start_resync_timer); | ||
2989 | mdev->resync_timer.function = resync_timer_fn; | 2991 | mdev->resync_timer.function = resync_timer_fn; |
2990 | mdev->resync_timer.data = (unsigned long) mdev; | 2992 | mdev->resync_timer.data = (unsigned long) mdev; |
2991 | mdev->md_sync_timer.function = md_sync_timer_fn; | 2993 | mdev->md_sync_timer.function = md_sync_timer_fn; |
2992 | mdev->md_sync_timer.data = (unsigned long) mdev; | 2994 | mdev->md_sync_timer.data = (unsigned long) mdev; |
2995 | mdev->start_resync_timer.function = start_resync_timer_fn; | ||
2996 | mdev->start_resync_timer.data = (unsigned long) mdev; | ||
2993 | 2997 | ||
2994 | init_waitqueue_head(&mdev->misc_wait); | 2998 | init_waitqueue_head(&mdev->misc_wait); |
2995 | init_waitqueue_head(&mdev->state_wait); | 2999 | init_waitqueue_head(&mdev->state_wait); |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 7991183749e3..18cb8b609fe4 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -4392,11 +4392,9 @@ static int got_BarrierAck(struct drbd_conf *mdev, struct p_header80 *h) | |||
4392 | 4392 | ||
4393 | if (mdev->state.conn == C_AHEAD && | 4393 | if (mdev->state.conn == C_AHEAD && |
4394 | atomic_read(&mdev->ap_in_flight) == 0 && | 4394 | atomic_read(&mdev->ap_in_flight) == 0 && |
4395 | atomic_read(&mdev->rs_pending_cnt) == 0 && | 4395 | !test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &mdev->current_epoch->flags)) { |
4396 | list_empty(&mdev->start_resync_work.list)) { | 4396 | mdev->start_resync_timer.expires = jiffies + HZ; |
4397 | struct drbd_work *w = &mdev->start_resync_work; | 4397 | add_timer(&mdev->start_resync_timer); |
4398 | w->cb = w_start_resync; | ||
4399 | drbd_queue_work(&mdev->data.work, w); | ||
4400 | } | 4398 | } |
4401 | 4399 | ||
4402 | return true; | 4400 | return true; |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 147f76b26810..3a95b701b5d0 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -712,10 +712,24 @@ static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int ca | |||
712 | } | 712 | } |
713 | 713 | ||
714 | 714 | ||
715 | void start_resync_timer_fn(unsigned long data) | ||
716 | { | ||
717 | struct drbd_conf *mdev = (struct drbd_conf *) data; | ||
718 | |||
719 | drbd_queue_work(&mdev->data.work, &mdev->start_resync_work); | ||
720 | } | ||
721 | |||
715 | int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | 722 | int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel) |
716 | { | 723 | { |
717 | drbd_start_resync(mdev, C_SYNC_SOURCE); | 724 | if (atomic_read(&mdev->unacked_cnt) || atomic_read(&mdev->rs_pending_cnt)) { |
725 | dev_warn(DEV, "w_start_resync later...\n"); | ||
726 | mdev->start_resync_timer.expires = jiffies + HZ/10; | ||
727 | add_timer(&mdev->start_resync_timer); | ||
728 | return 1; | ||
729 | } | ||
718 | 730 | ||
731 | drbd_start_resync(mdev, C_SYNC_SOURCE); | ||
732 | clear_bit(AHEAD_TO_SYNC_SOURCE, &mdev->current_epoch->flags); | ||
719 | return 1; | 733 | return 1; |
720 | } | 734 | } |
721 | 735 | ||