dm cache: pass a new 'critical' flag to the policies when requesting writeback work
authorJoe Thornber <ejt@redhat.com>
Fri, 15 May 2015 14:20:09 +0000 (15:20 +0100)
committerMike Snitzer <snitzer@redhat.com>
Fri, 29 May 2015 18:19:04 +0000 (14:19 -0400)
We only allow non critical writeback if the origin is idle.  It is up
to the policy to decide what writeback work is critical.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-cache-policy-cleaner.c
drivers/md/dm-cache-policy-internal.h
drivers/md/dm-cache-policy-mq.c
drivers/md/dm-cache-policy.h
drivers/md/dm-cache-target.c

index 004e463c9423cd7fe81d8f2256b63877b02aebf0..240c9f0e85e74e864624f0cb972c5b4394eaf11f 100644 (file)
@@ -359,7 +359,8 @@ static struct wb_cache_entry *get_next_dirty_entry(struct policy *p)
 
 static int wb_writeback_work(struct dm_cache_policy *pe,
                             dm_oblock_t *oblock,
-                            dm_cblock_t *cblock)
+                            dm_cblock_t *cblock,
+                            bool critical_only)
 {
        int r = -ENOENT;
        struct policy *p = to_policy(pe);
index c198e6defb9cd53009b2c61ba0dd1ae3c30d6483..776c685167e660bb6e37af9ec7a843584f54a44c 100644 (file)
@@ -55,9 +55,10 @@ static inline int policy_walk_mappings(struct dm_cache_policy *p,
 
 static inline int policy_writeback_work(struct dm_cache_policy *p,
                                        dm_oblock_t *oblock,
-                                       dm_cblock_t *cblock)
+                                       dm_cblock_t *cblock,
+                                       bool critical_only)
 {
-       return p->writeback_work ? p->writeback_work(p, oblock, cblock) : -ENOENT;
+       return p->writeback_work ? p->writeback_work(p, oblock, cblock, critical_only) : -ENOENT;
 }
 
 static inline void policy_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock)
index 515d44bf24d3de874a3a58f521de7446710c4527..7cbae125879c7079bc87c7fb3d96ea13462a782e 100644 (file)
@@ -1236,7 +1236,7 @@ static int __mq_writeback_work(struct mq_policy *mq, dm_oblock_t *oblock,
 }
 
 static int mq_writeback_work(struct dm_cache_policy *p, dm_oblock_t *oblock,
-                            dm_cblock_t *cblock)
+                            dm_cblock_t *cblock, bool critical_only)
 {
        int r;
        struct mq_policy *mq = to_mq_policy(p);
index 5524e21e483654d5dc44b8b8944f9404b84b0292..6106ca3aa350a62326558e61c296e801b9fbe12b 100644 (file)
@@ -178,7 +178,9 @@ struct dm_cache_policy {
        int (*remove_cblock)(struct dm_cache_policy *p, dm_cblock_t cblock);
 
        /*
-        * Provide a dirty block to be written back by the core target.
+        * Provide a dirty block to be written back by the core target.  If
+        * critical_only is set then the policy should only provide work if
+        * it urgently needs it.
         *
         * Returns:
         *
@@ -186,7 +188,8 @@ struct dm_cache_policy {
         *
         * -ENODATA: no dirty blocks available
         */
-       int (*writeback_work)(struct dm_cache_policy *p, dm_oblock_t *oblock, dm_cblock_t *cblock);
+       int (*writeback_work)(struct dm_cache_policy *p, dm_oblock_t *oblock, dm_cblock_t *cblock,
+                             bool critical_only);
 
        /*
         * How full is the cache?
index 940c7b2b5ab44163bef02d094f02b9971a0d0175..5a9cd2c5a359f64d7fea598747f26251558ea4d9 100644 (file)
@@ -1787,6 +1787,7 @@ static void writeback_some_dirty_blocks(struct cache *cache)
        dm_cblock_t cblock;
        struct prealloc structs;
        struct dm_bio_prison_cell *old_ocell;
+       bool busy = !iot_idle_for(&cache->origin_tracker, HZ);
 
        memset(&structs, 0, sizeof(structs));
 
@@ -1794,7 +1795,7 @@ static void writeback_some_dirty_blocks(struct cache *cache)
                if (prealloc_data_structs(cache, &structs))
                        break;
 
-               r = policy_writeback_work(cache->policy, &oblock, &cblock);
+               r = policy_writeback_work(cache->policy, &oblock, &cblock, busy);
                if (r)
                        break;