diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2010-11-09 07:59:41 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-10 05:34:56 -0500 |
commit | f91ab6282df251d28aa4ad1bd85194ebe0a0115b (patch) | |
tree | 1c696b201c9eaea365e8d80bb3956827a0a880e7 /drivers/block | |
parent | 9d77a5fee9d2a1ea4cd9a841d27b107df5913b33 (diff) |
drbd: Implemented side-stepping in drbd_res_begin_io()
Before:
drbd_rs_begin_io() locked app-IO out of an RS extent, and
waited then until all previous app-IO in that area finished.
(But not only until the disk-IO was finished but until the
barrier/epoch ack came in for that == round trip time latency ++)
After:
As soon as a new app-IO waits wants to start new IO on that
RS extent, drbd_rs_begin_io() steps aside (clearing the
BME_NO_WRITES flag again). It retries after 100ms.
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_actlog.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 28f85d950781..5570d9bdc863 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -176,14 +176,17 @@ static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) | |||
176 | struct lc_element *al_ext; | 176 | struct lc_element *al_ext; |
177 | struct lc_element *tmp; | 177 | struct lc_element *tmp; |
178 | unsigned long al_flags = 0; | 178 | unsigned long al_flags = 0; |
179 | int wake; | ||
179 | 180 | ||
180 | spin_lock_irq(&mdev->al_lock); | 181 | spin_lock_irq(&mdev->al_lock); |
181 | tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); | 182 | tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); |
182 | if (unlikely(tmp != NULL)) { | 183 | if (unlikely(tmp != NULL)) { |
183 | struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); | 184 | struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); |
184 | if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { | 185 | if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { |
185 | set_bit(BME_PRIORITY, &bm_ext->flags); | 186 | wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags); |
186 | spin_unlock_irq(&mdev->al_lock); | 187 | spin_unlock_irq(&mdev->al_lock); |
188 | if (wake) | ||
189 | wake_up(&mdev->al_wait); | ||
187 | return NULL; | 190 | return NULL; |
188 | } | 191 | } |
189 | } | 192 | } |
@@ -1135,7 +1138,10 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) | |||
1135 | unsigned int enr = BM_SECT_TO_EXT(sector); | 1138 | unsigned int enr = BM_SECT_TO_EXT(sector); |
1136 | struct bm_extent *bm_ext; | 1139 | struct bm_extent *bm_ext; |
1137 | int i, sig; | 1140 | int i, sig; |
1141 | int sa = 200; /* Step aside 200 times, then grab the extent and let app-IO wait. | ||
1142 | 200 times -> 20 seconds. */ | ||
1138 | 1143 | ||
1144 | retry: | ||
1139 | sig = wait_event_interruptible(mdev->al_wait, | 1145 | sig = wait_event_interruptible(mdev->al_wait, |
1140 | (bm_ext = _bme_get(mdev, enr))); | 1146 | (bm_ext = _bme_get(mdev, enr))); |
1141 | if (sig) | 1147 | if (sig) |
@@ -1146,16 +1152,24 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) | |||
1146 | 1152 | ||
1147 | for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { | 1153 | for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { |
1148 | sig = wait_event_interruptible(mdev->al_wait, | 1154 | sig = wait_event_interruptible(mdev->al_wait, |
1149 | !_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i)); | 1155 | !_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i) || |
1150 | if (sig) { | 1156 | (test_bit(BME_PRIORITY, &bm_ext->flags) && sa)); |
1157 | |||
1158 | if (sig || (test_bit(BME_PRIORITY, &bm_ext->flags) && sa)) { | ||
1151 | spin_lock_irq(&mdev->al_lock); | 1159 | spin_lock_irq(&mdev->al_lock); |
1152 | if (lc_put(mdev->resync, &bm_ext->lce) == 0) { | 1160 | if (lc_put(mdev->resync, &bm_ext->lce) == 0) { |
1153 | clear_bit(BME_NO_WRITES, &bm_ext->flags); | 1161 | bm_ext->flags = 0; /* clears BME_NO_WRITES and eventually BME_PRIORITY */ |
1154 | mdev->resync_locked--; | 1162 | mdev->resync_locked--; |
1155 | wake_up(&mdev->al_wait); | 1163 | wake_up(&mdev->al_wait); |
1156 | } | 1164 | } |
1157 | spin_unlock_irq(&mdev->al_lock); | 1165 | spin_unlock_irq(&mdev->al_lock); |
1158 | return -EINTR; | 1166 | if (sig) |
1167 | return -EINTR; | ||
1168 | if (schedule_timeout_interruptible(HZ/10)) | ||
1169 | return -EINTR; | ||
1170 | if (--sa == 0) | ||
1171 | dev_warn(DEV,"drbd_rs_begin_io() no longer stepping aside.\n"); | ||
1172 | goto retry; | ||
1159 | } | 1173 | } |
1160 | } | 1174 | } |
1161 | set_bit(BME_LOCKED, &bm_ext->flags); | 1175 | set_bit(BME_LOCKED, &bm_ext->flags); |