Skip to content

Commit 905e51b

Browse files
jthornberkergon
authored andcommitted
dm thin: commit outstanding data every second
Commit unwritten data every second to prevent too much building up. Released blocks don't become available until after the next commit (for crash resilience). Prior to this patch commits were only triggered by a message to the target or a REQ_{FLUSH,FUA} bio. This allowed far too big a position to build up. The interval is hard-coded to 1 second. This is a sensible setting. I'm not making this user configurable, since there isn't much to be gained by tweaking this - and a lot lost by setting it far too high. Signed-off-by: Joe Thornber <[email protected]> Signed-off-by: Mike Snitzer <[email protected]> Signed-off-by: Alasdair G Kergon <[email protected]>
1 parent 31998ef commit 905e51b

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

drivers/md/dm-thin.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define DEFERRED_SET_SIZE 64
2424
#define MAPPING_POOL_SIZE 1024
2525
#define PRISON_CELLS 1024
26+
#define COMMIT_PERIOD HZ
2627

2728
/*
2829
* The block size of the device holding pool data must be
@@ -520,8 +521,10 @@ struct pool {
520521

521522
struct workqueue_struct *wq;
522523
struct work_struct worker;
524+
struct delayed_work waker;
523525

524526
unsigned ref_count;
527+
unsigned long last_commit_jiffies;
525528

526529
spinlock_t lock;
527530
struct bio_list deferred_bios;
@@ -1271,6 +1274,12 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
12711274
}
12721275
}
12731276

1277+
static int need_commit_due_to_time(struct pool *pool)
1278+
{
1279+
return jiffies < pool->last_commit_jiffies ||
1280+
jiffies > pool->last_commit_jiffies + COMMIT_PERIOD;
1281+
}
1282+
12741283
static void process_deferred_bios(struct pool *pool)
12751284
{
12761285
unsigned long flags;
@@ -1312,7 +1321,7 @@ static void process_deferred_bios(struct pool *pool)
13121321
bio_list_init(&pool->deferred_flush_bios);
13131322
spin_unlock_irqrestore(&pool->lock, flags);
13141323

1315-
if (bio_list_empty(&bios))
1324+
if (bio_list_empty(&bios) && !need_commit_due_to_time(pool))
13161325
return;
13171326

13181327
r = dm_pool_commit_metadata(pool->pmd);
@@ -1323,6 +1332,7 @@ static void process_deferred_bios(struct pool *pool)
13231332
bio_io_error(bio);
13241333
return;
13251334
}
1335+
pool->last_commit_jiffies = jiffies;
13261336

13271337
while ((bio = bio_list_pop(&bios)))
13281338
generic_make_request(bio);
@@ -1336,6 +1346,17 @@ static void do_worker(struct work_struct *ws)
13361346
process_deferred_bios(pool);
13371347
}
13381348

1349+
/*
1350+
* We want to commit periodically so that not too much
1351+
* unwritten data builds up.
1352+
*/
1353+
static void do_waker(struct work_struct *ws)
1354+
{
1355+
struct pool *pool = container_of(to_delayed_work(ws), struct pool, waker);
1356+
wake_worker(pool);
1357+
queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD);
1358+
}
1359+
13391360
/*----------------------------------------------------------------*/
13401361

13411362
/*
@@ -1545,6 +1566,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
15451566
}
15461567

15471568
INIT_WORK(&pool->worker, do_worker);
1569+
INIT_DELAYED_WORK(&pool->waker, do_waker);
15481570
spin_lock_init(&pool->lock);
15491571
bio_list_init(&pool->deferred_bios);
15501572
bio_list_init(&pool->deferred_flush_bios);
@@ -1571,6 +1593,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
15711593
goto bad_endio_hook_pool;
15721594
}
15731595
pool->ref_count = 1;
1596+
pool->last_commit_jiffies = jiffies;
15741597
pool->pool_md = pool_md;
15751598
pool->md_dev = metadata_dev;
15761599
__pool_table_insert(pool);
@@ -1900,7 +1923,7 @@ static void pool_resume(struct dm_target *ti)
19001923
__requeue_bios(pool);
19011924
spin_unlock_irqrestore(&pool->lock, flags);
19021925

1903-
wake_worker(pool);
1926+
do_waker(&pool->waker.work);
19041927
}
19051928

19061929
static void pool_postsuspend(struct dm_target *ti)
@@ -1909,6 +1932,7 @@ static void pool_postsuspend(struct dm_target *ti)
19091932
struct pool_c *pt = ti->private;
19101933
struct pool *pool = pt->pool;
19111934

1935+
cancel_delayed_work(&pool->waker);
19121936
flush_workqueue(pool->wq);
19131937

19141938
r = dm_pool_commit_metadata(pool->pmd);

0 commit comments

Comments
 (0)