aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2008-04-24 17:10:42 -0400
committerAlasdair G Kergon <agk@redhat.com>2008-04-25 08:26:56 -0400
commita2aebe03be60ae4da03507a00d60211d5e0327c3 (patch)
tree9475bf530b36f3f4a26c8307d94b3c53787d9ef2 /drivers/md
parenta765e20eeb423d0fa6a02ffab51141e53bbd93cb (diff)
dm raid1: use timer
This patch replaces the schedule() in the main kmirrord thread with a timer. The schedule() could introduce an unwanted delay when work is ready to be processed. The code instead calls wake() when there's work to be done immediately, and delayed_wake() after a failure to give a short delay before retrying. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-raid1.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 6692e5a84bb1..3b9532fc294c 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -154,6 +154,9 @@ struct mirror_set {
154 154
155 struct workqueue_struct *kmirrord_wq; 155 struct workqueue_struct *kmirrord_wq;
156 struct work_struct kmirrord_work; 156 struct work_struct kmirrord_work;
157 struct timer_list timer;
158 unsigned long timer_pending;
159
157 struct work_struct trigger_event; 160 struct work_struct trigger_event;
158 161
159 unsigned int nr_mirrors; 162 unsigned int nr_mirrors;
@@ -178,6 +181,25 @@ static void wake(struct mirror_set *ms)
178 queue_work(ms->kmirrord_wq, &ms->kmirrord_work); 181 queue_work(ms->kmirrord_wq, &ms->kmirrord_work);
179} 182}
180 183
184static void delayed_wake_fn(unsigned long data)
185{
186 struct mirror_set *ms = (struct mirror_set *) data;
187
188 clear_bit(0, &ms->timer_pending);
189 wake(ms);
190}
191
192static void delayed_wake(struct mirror_set *ms)
193{
194 if (test_and_set_bit(0, &ms->timer_pending))
195 return;
196
197 ms->timer.expires = jiffies + HZ / 5;
198 ms->timer.data = (unsigned long) ms;
199 ms->timer.function = delayed_wake_fn;
200 add_timer(&ms->timer);
201}
202
181/* FIXME move this */ 203/* FIXME move this */
182static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw); 204static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw);
183 205
@@ -1180,6 +1202,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
1180 spin_lock_irq(&ms->lock); 1202 spin_lock_irq(&ms->lock);
1181 bio_list_merge(&ms->failures, &sync); 1203 bio_list_merge(&ms->failures, &sync);
1182 spin_unlock_irq(&ms->lock); 1204 spin_unlock_irq(&ms->lock);
1205 wake(ms);
1183 } else 1206 } else
1184 while ((bio = bio_list_pop(&sync))) 1207 while ((bio = bio_list_pop(&sync)))
1185 do_write(ms, bio); 1208 do_write(ms, bio);
@@ -1239,7 +1262,7 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures)
1239 bio_list_merge(&ms->failures, failures); 1262 bio_list_merge(&ms->failures, failures);
1240 spin_unlock_irq(&ms->lock); 1263 spin_unlock_irq(&ms->lock);
1241 1264
1242 wake(ms); 1265 delayed_wake(ms);
1243} 1266}
1244 1267
1245static void trigger_event(struct work_struct *work) 1268static void trigger_event(struct work_struct *work)
@@ -1253,7 +1276,7 @@ static void trigger_event(struct work_struct *work)
1253/*----------------------------------------------------------------- 1276/*-----------------------------------------------------------------
1254 * kmirrord 1277 * kmirrord
1255 *---------------------------------------------------------------*/ 1278 *---------------------------------------------------------------*/
1256static int _do_mirror(struct work_struct *work) 1279static void do_mirror(struct work_struct *work)
1257{ 1280{
1258 struct mirror_set *ms =container_of(work, struct mirror_set, 1281 struct mirror_set *ms =container_of(work, struct mirror_set,
1259 kmirrord_work); 1282 kmirrord_work);
@@ -1274,24 +1297,6 @@ static int _do_mirror(struct work_struct *work)
1274 do_reads(ms, &reads); 1297 do_reads(ms, &reads);
1275 do_writes(ms, &writes); 1298 do_writes(ms, &writes);
1276 do_failures(ms, &failures); 1299 do_failures(ms, &failures);
1277
1278 return (ms->failures.head) ? 1 : 0;
1279}
1280
1281static void do_mirror(struct work_struct *work)
1282{
1283 /*
1284 * If _do_mirror returns 1, we give it
1285 * another shot. This helps for cases like
1286 * 'suspend' where we call flush_workqueue
1287 * and expect all work to be finished. If
1288 * a failure happens during a suspend, we
1289 * couldn't issue a 'wake' because it would
1290 * not be honored. Therefore, we return '1'
1291 * from _do_mirror, and retry here.
1292 */
1293 while (_do_mirror(work))
1294 schedule();
1295} 1300}
1296 1301
1297 1302
@@ -1545,6 +1550,8 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1545 goto err_free_context; 1550 goto err_free_context;
1546 } 1551 }
1547 INIT_WORK(&ms->kmirrord_work, do_mirror); 1552 INIT_WORK(&ms->kmirrord_work, do_mirror);
1553 init_timer(&ms->timer);
1554 ms->timer_pending = 0;
1548 INIT_WORK(&ms->trigger_event, trigger_event); 1555 INIT_WORK(&ms->trigger_event, trigger_event);
1549 1556
1550 r = parse_features(ms, argc, argv, &args_used); 1557 r = parse_features(ms, argc, argv, &args_used);
@@ -1587,6 +1594,7 @@ static void mirror_dtr(struct dm_target *ti)
1587{ 1594{
1588 struct mirror_set *ms = (struct mirror_set *) ti->private; 1595 struct mirror_set *ms = (struct mirror_set *) ti->private;
1589 1596
1597 del_timer_sync(&ms->timer);
1590 flush_workqueue(ms->kmirrord_wq); 1598 flush_workqueue(ms->kmirrord_wq);
1591 dm_kcopyd_client_destroy(ms->kcopyd_client); 1599 dm_kcopyd_client_destroy(ms->kcopyd_client);
1592 destroy_workqueue(ms->kmirrord_wq); 1600 destroy_workqueue(ms->kmirrord_wq);