dm cache: use cell_defer() boolean argument consistently
[cascardo/linux.git] / drivers / md / dm-cache-target.c
index 0df3ec0..dc63eb2 100644 (file)
@@ -67,9 +67,11 @@ static void free_bitset(unsigned long *bits)
 #define MIGRATION_COUNT_WINDOW 10
 
 /*
- * The block size of the device holding cache data must be >= 32KB
+ * The block size of the device holding cache data must be
+ * between 32KB and 1GB.
  */
 #define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (32 * 1024 >> SECTOR_SHIFT)
+#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
 
 /*
  * FIXME: the cache is read/write for the time being.
@@ -101,6 +103,8 @@ struct cache {
        struct dm_target *ti;
        struct dm_target_callbacks callbacks;
 
+       struct dm_cache_metadata *cmd;
+
        /*
         * Metadata is written to this device.
         */
@@ -116,11 +120,6 @@ struct cache {
         */
        struct dm_dev *cache_dev;
 
-       /*
-        * Cache features such as write-through.
-        */
-       struct cache_features features;
-
        /*
         * Size of the origin device in _complete_ blocks and native sectors.
         */
@@ -138,8 +137,6 @@ struct cache {
        uint32_t sectors_per_block;
        int sectors_per_block_shift;
 
-       struct dm_cache_metadata *cmd;
-
        spinlock_t lock;
        struct bio_list deferred_bios;
        struct bio_list deferred_flush_bios;
@@ -148,8 +145,12 @@ struct cache {
        struct list_head completed_migrations;
        struct list_head need_commit_migrations;
        sector_t migration_threshold;
-       atomic_t nr_migrations;
        wait_queue_head_t migration_wait;
+       atomic_t nr_migrations;
+
+       wait_queue_head_t quiescing_wait;
+       atomic_t quiescing;
+       atomic_t quiescing_ack;
 
        /*
         * cache_size entries, dirty if set
@@ -160,9 +161,16 @@ struct cache {
        /*
         * origin_blocks entries, discarded if set.
         */
-       uint32_t discard_block_size; /* a power of 2 times sectors per block */
        dm_dblock_t discard_nr_blocks;
        unsigned long *discard_bitset;
+       uint32_t discard_block_size; /* a power of 2 times sectors per block */
+
+       /*
+        * Rather than reconstructing the table line for the status we just
+        * save it and regurgitate.
+        */
+       unsigned nr_ctr_args;
+       const char **ctr_args;
 
        struct dm_kcopyd_client *copier;
        struct workqueue_struct *wq;
@@ -182,19 +190,16 @@ struct cache {
 
        bool need_tick_bio:1;
        bool sized:1;
-       bool quiescing:1;
        bool commit_requested:1;
        bool loaded_mappings:1;
        bool loaded_discards:1;
 
-       struct cache_stats stats;
-
        /*
-        * Rather than reconstructing the table line for the status we just
-        * save it and regurgitate.
+        * Cache features such as write-through.
         */
-       unsigned nr_ctr_args;
-       const char **ctr_args;
+       struct cache_features features;
+
+       struct cache_stats stats;
 };
 
 struct per_bio_data {
@@ -603,6 +608,7 @@ static void remap_to_origin_clear_discard(struct cache *cache, struct bio *bio,
 static void remap_to_cache_dirty(struct cache *cache, struct bio *bio,
                                 dm_oblock_t oblock, dm_cblock_t cblock)
 {
+       check_if_tick_bio_needed(cache, bio);
        remap_to_cache(cache, bio, cblock);
        if (bio_data_dir(bio) == WRITE) {
                set_dirty(cache, oblock, cblock);
@@ -746,8 +752,9 @@ static void cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell,
 
 static void cleanup_migration(struct dm_cache_migration *mg)
 {
-       dec_nr_migrations(mg->cache);
+       struct cache *cache = mg->cache;
        free_migration(mg);
+       dec_nr_migrations(cache);
 }
 
 static void migration_failure(struct dm_cache_migration *mg)
@@ -763,13 +770,13 @@ static void migration_failure(struct dm_cache_migration *mg)
                DMWARN_LIMIT("demotion failed; couldn't copy block");
                policy_force_mapping(cache->policy, mg->new_oblock, mg->old_oblock);
 
-               cell_defer(cache, mg->old_ocell, mg->promote ? 0 : 1);
+               cell_defer(cache, mg->old_ocell, mg->promote ? false : true);
                if (mg->promote)
-                       cell_defer(cache, mg->new_ocell, 1);
+                       cell_defer(cache, mg->new_ocell, true);
        } else {
                DMWARN_LIMIT("promotion failed; couldn't copy block");
                policy_remove_mapping(cache->policy, mg->new_oblock);
-               cell_defer(cache, mg->new_ocell, 1);
+               cell_defer(cache, mg->new_ocell, true);
        }
 
        cleanup_migration(mg);
@@ -821,7 +828,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg)
                return;
 
        } else if (mg->demote) {
-               cell_defer(cache, mg->old_ocell, mg->promote ? 0 : 1);
+               cell_defer(cache, mg->old_ocell, mg->promote ? false : true);
 
                if (mg->promote) {
                        mg->demote = false;
@@ -1344,34 +1351,34 @@ static void writeback_some_dirty_blocks(struct cache *cache)
 /*----------------------------------------------------------------
  * Main worker loop
  *--------------------------------------------------------------*/
-static void start_quiescing(struct cache *cache)
+static bool is_quiescing(struct cache *cache)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&cache->lock, flags);
-       cache->quiescing = 1;
-       spin_unlock_irqrestore(&cache->lock, flags);
+       return atomic_read(&cache->quiescing);
 }
 
-static void stop_quiescing(struct cache *cache)
+static void ack_quiescing(struct cache *cache)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&cache->lock, flags);
-       cache->quiescing = 0;
-       spin_unlock_irqrestore(&cache->lock, flags);
+       if (is_quiescing(cache)) {
+               atomic_inc(&cache->quiescing_ack);
+               wake_up(&cache->quiescing_wait);
+       }
 }
 
-static bool is_quiescing(struct cache *cache)
+static void wait_for_quiescing_ack(struct cache *cache)
 {
-       int r;
-       unsigned long flags;
+       wait_event(cache->quiescing_wait, atomic_read(&cache->quiescing_ack));
+}
 
-       spin_lock_irqsave(&cache->lock, flags);
-       r = cache->quiescing;
-       spin_unlock_irqrestore(&cache->lock, flags);
+static void start_quiescing(struct cache *cache)
+{
+       atomic_inc(&cache->quiescing);
+       wait_for_quiescing_ack(cache);
+}
 
-       return r;
+static void stop_quiescing(struct cache *cache)
+{
+       atomic_set(&cache->quiescing, 0);
+       atomic_set(&cache->quiescing_ack, 0);
 }
 
 static void wait_for_migrations(struct cache *cache)
@@ -1418,16 +1425,15 @@ static void do_worker(struct work_struct *ws)
        struct cache *cache = container_of(ws, struct cache, worker);
 
        do {
-               if (!is_quiescing(cache))
+               if (!is_quiescing(cache)) {
+                       writeback_some_dirty_blocks(cache);
+                       process_deferred_writethrough_bios(cache);
                        process_deferred_bios(cache);
+               }
 
                process_migrations(cache, &cache->quiesced_migrations, issue_copy);
                process_migrations(cache, &cache->completed_migrations, complete_migration);
 
-               writeback_some_dirty_blocks(cache);
-
-               process_deferred_writethrough_bios(cache);
-
                if (commit_if_needed(cache)) {
                        process_deferred_flush_bios(cache, false);
 
@@ -1440,6 +1446,9 @@ static void do_worker(struct work_struct *ws)
                        process_migrations(cache, &cache->need_commit_migrations,
                                           migration_success_post_commit);
                }
+
+               ack_quiescing(cache);
+
        } while (more_work(cache));
 }
 
@@ -1687,24 +1696,25 @@ static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as,
 static int parse_block_size(struct cache_args *ca, struct dm_arg_set *as,
                            char **error)
 {
-       unsigned long tmp;
+       unsigned long block_size;
 
        if (!at_least_one_arg(as, error))
                return -EINVAL;
 
-       if (kstrtoul(dm_shift_arg(as), 10, &tmp) || !tmp ||
-           tmp < DATA_DEV_BLOCK_SIZE_MIN_SECTORS ||
-           tmp & (DATA_DEV_BLOCK_SIZE_MIN_SECTORS - 1)) {
+       if (kstrtoul(dm_shift_arg(as), 10, &block_size) || !block_size ||
+           block_size < DATA_DEV_BLOCK_SIZE_MIN_SECTORS ||
+           block_size > DATA_DEV_BLOCK_SIZE_MAX_SECTORS ||
+           block_size & (DATA_DEV_BLOCK_SIZE_MIN_SECTORS - 1)) {
                *error = "Invalid data block size";
                return -EINVAL;
        }
 
-       if (tmp > ca->cache_sectors) {
+       if (block_size > ca->cache_sectors) {
                *error = "Data block size is larger than the cache device";
                return -EINVAL;
        }
 
-       ca->block_size = tmp;
+       ca->block_size = block_size;
 
        return 0;
 }
@@ -1869,14 +1879,15 @@ static int set_config_values(struct cache *cache, int argc, const char **argv)
 static int create_cache_policy(struct cache *cache, struct cache_args *ca,
                               char **error)
 {
-       cache->policy = dm_cache_policy_create(ca->policy_name,
-                                              cache->cache_size,
-                                              cache->origin_sectors,
-                                              cache->sectors_per_block);
-       if (!cache->policy) {
+       struct dm_cache_policy *p = dm_cache_policy_create(ca->policy_name,
+                                                          cache->cache_size,
+                                                          cache->origin_sectors,
+                                                          cache->sectors_per_block);
+       if (IS_ERR(p)) {
                *error = "Error creating cache's policy";
-               return -ENOMEM;
+               return PTR_ERR(p);
        }
+       cache->policy = p;
 
        return 0;
 }
@@ -2002,6 +2013,10 @@ static int cache_create(struct cache_args *ca, struct cache **result)
        atomic_set(&cache->nr_migrations, 0);
        init_waitqueue_head(&cache->migration_wait);
 
+       init_waitqueue_head(&cache->quiescing_wait);
+       atomic_set(&cache->quiescing, 0);
+       atomic_set(&cache->quiescing_ack, 0);
+
        r = -ENOMEM;
        cache->nr_dirty = 0;
        cache->dirty_bitset = alloc_bitset(from_cblock(cache->cache_size));
@@ -2061,7 +2076,6 @@ static int cache_create(struct cache_args *ca, struct cache **result)
 
        cache->need_tick_bio = true;
        cache->sized = false;
-       cache->quiescing = false;
        cache->commit_requested = false;
        cache->loaded_mappings = false;
        cache->loaded_discards = false;
@@ -2609,9 +2623,17 @@ static void set_discard_limits(struct cache *cache, struct queue_limits *limits)
 static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct cache *cache = ti->private;
+       uint64_t io_opt_sectors = limits->io_opt >> SECTOR_SHIFT;
 
-       blk_limits_io_min(limits, 0);
-       blk_limits_io_opt(limits, cache->sectors_per_block << SECTOR_SHIFT);
+       /*
+        * If the system-determined stacked limits are compatible with the
+        * cache's blocksize (io_opt is a factor) do not override them.
+        */
+       if (io_opt_sectors < cache->sectors_per_block ||
+           do_div(io_opt_sectors, cache->sectors_per_block)) {
+               blk_limits_io_min(limits, 0);
+               blk_limits_io_opt(limits, cache->sectors_per_block << SECTOR_SHIFT);
+       }
        set_discard_limits(cache, limits);
 }