aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-11-09 07:59:41 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 05:34:56 -0500
commitf91ab6282df251d28aa4ad1bd85194ebe0a0115b (patch)
tree1c696b201c9eaea365e8d80bb3956827a0a880e7 /drivers/block
parent9d77a5fee9d2a1ea4cd9a841d27b107df5913b33 (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.c24
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
1144retry:
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);