Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (C) 2017 Western Digital Corporation or its affiliates.
0004  *
0005  * This file is released under the GPL.
0006  */
0007 
0008 #ifndef DM_ZONED_H
0009 #define DM_ZONED_H
0010 
0011 #include <linux/types.h>
0012 #include <linux/blkdev.h>
0013 #include <linux/device-mapper.h>
0014 #include <linux/dm-kcopyd.h>
0015 #include <linux/list.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/mutex.h>
0018 #include <linux/workqueue.h>
0019 #include <linux/rwsem.h>
0020 #include <linux/rbtree.h>
0021 #include <linux/radix-tree.h>
0022 #include <linux/shrinker.h>
0023 
0024 /*
0025  * dm-zoned creates block devices with 4KB blocks, always.
0026  */
0027 #define DMZ_BLOCK_SHIFT     12
0028 #define DMZ_BLOCK_SIZE      (1 << DMZ_BLOCK_SHIFT)
0029 #define DMZ_BLOCK_MASK      (DMZ_BLOCK_SIZE - 1)
0030 
0031 #define DMZ_BLOCK_SHIFT_BITS    (DMZ_BLOCK_SHIFT + 3)
0032 #define DMZ_BLOCK_SIZE_BITS (1 << DMZ_BLOCK_SHIFT_BITS)
0033 #define DMZ_BLOCK_MASK_BITS (DMZ_BLOCK_SIZE_BITS - 1)
0034 
0035 #define DMZ_BLOCK_SECTORS_SHIFT (DMZ_BLOCK_SHIFT - SECTOR_SHIFT)
0036 #define DMZ_BLOCK_SECTORS   (DMZ_BLOCK_SIZE >> SECTOR_SHIFT)
0037 #define DMZ_BLOCK_SECTORS_MASK  (DMZ_BLOCK_SECTORS - 1)
0038 
0039 /*
0040  * 4KB block <-> 512B sector conversion.
0041  */
0042 #define dmz_blk2sect(b)     ((sector_t)(b) << DMZ_BLOCK_SECTORS_SHIFT)
0043 #define dmz_sect2blk(s)     ((sector_t)(s) >> DMZ_BLOCK_SECTORS_SHIFT)
0044 
0045 #define dmz_bio_block(bio)  dmz_sect2blk((bio)->bi_iter.bi_sector)
0046 #define dmz_bio_blocks(bio) dmz_sect2blk(bio_sectors(bio))
0047 
0048 struct dmz_metadata;
0049 struct dmz_reclaim;
0050 
0051 /*
0052  * Zoned block device information.
0053  */
0054 struct dmz_dev {
0055     struct block_device *bdev;
0056     struct dmz_metadata *metadata;
0057     struct dmz_reclaim  *reclaim;
0058 
0059     uuid_t          uuid;
0060 
0061     sector_t        capacity;
0062 
0063     unsigned int        dev_idx;
0064 
0065     unsigned int        nr_zones;
0066     unsigned int        zone_offset;
0067 
0068     unsigned int        flags;
0069 
0070     sector_t        zone_nr_sectors;
0071 
0072     unsigned int        nr_rnd;
0073     atomic_t        unmap_nr_rnd;
0074     struct list_head    unmap_rnd_list;
0075     struct list_head    map_rnd_list;
0076 
0077     unsigned int        nr_seq;
0078     atomic_t        unmap_nr_seq;
0079     struct list_head    unmap_seq_list;
0080     struct list_head    map_seq_list;
0081 };
0082 
0083 #define dmz_bio_chunk(zmd, bio) ((bio)->bi_iter.bi_sector >> \
0084                  dmz_zone_nr_sectors_shift(zmd))
0085 #define dmz_chunk_block(zmd, b) ((b) & (dmz_zone_nr_blocks(zmd) - 1))
0086 
0087 /* Device flags. */
0088 #define DMZ_BDEV_DYING      (1 << 0)
0089 #define DMZ_CHECK_BDEV      (2 << 0)
0090 #define DMZ_BDEV_REGULAR    (4 << 0)
0091 
0092 /*
0093  * Zone descriptor.
0094  */
0095 struct dm_zone {
0096     /* For listing the zone depending on its state */
0097     struct list_head    link;
0098 
0099     /* Device containing this zone */
0100     struct dmz_dev      *dev;
0101 
0102     /* Zone type and state */
0103     unsigned long       flags;
0104 
0105     /* Zone activation reference count */
0106     atomic_t        refcount;
0107 
0108     /* Zone id */
0109     unsigned int        id;
0110 
0111     /* Zone write pointer block (relative to the zone start block) */
0112     unsigned int        wp_block;
0113 
0114     /* Zone weight (number of valid blocks in the zone) */
0115     unsigned int        weight;
0116 
0117     /* The chunk that the zone maps */
0118     unsigned int        chunk;
0119 
0120     /*
0121      * For a sequential data zone, pointer to the random zone
0122      * used as a buffer for processing unaligned writes.
0123      * For a buffer zone, this points back to the data zone.
0124      */
0125     struct dm_zone      *bzone;
0126 };
0127 
0128 /*
0129  * Zone flags.
0130  */
0131 enum {
0132     /* Zone write type */
0133     DMZ_CACHE,
0134     DMZ_RND,
0135     DMZ_SEQ,
0136 
0137     /* Zone critical condition */
0138     DMZ_OFFLINE,
0139     DMZ_READ_ONLY,
0140 
0141     /* How the zone is being used */
0142     DMZ_META,
0143     DMZ_DATA,
0144     DMZ_BUF,
0145     DMZ_RESERVED,
0146 
0147     /* Zone internal state */
0148     DMZ_RECLAIM,
0149     DMZ_SEQ_WRITE_ERR,
0150     DMZ_RECLAIM_TERMINATE,
0151 };
0152 
0153 /*
0154  * Zone data accessors.
0155  */
0156 #define dmz_is_cache(z)     test_bit(DMZ_CACHE, &(z)->flags)
0157 #define dmz_is_rnd(z)       test_bit(DMZ_RND, &(z)->flags)
0158 #define dmz_is_seq(z)       test_bit(DMZ_SEQ, &(z)->flags)
0159 #define dmz_is_empty(z)     ((z)->wp_block == 0)
0160 #define dmz_is_offline(z)   test_bit(DMZ_OFFLINE, &(z)->flags)
0161 #define dmz_is_readonly(z)  test_bit(DMZ_READ_ONLY, &(z)->flags)
0162 #define dmz_in_reclaim(z)   test_bit(DMZ_RECLAIM, &(z)->flags)
0163 #define dmz_is_reserved(z)  test_bit(DMZ_RESERVED, &(z)->flags)
0164 #define dmz_seq_write_err(z)    test_bit(DMZ_SEQ_WRITE_ERR, &(z)->flags)
0165 #define dmz_reclaim_should_terminate(z) \
0166                 test_bit(DMZ_RECLAIM_TERMINATE, &(z)->flags)
0167 
0168 #define dmz_is_meta(z)      test_bit(DMZ_META, &(z)->flags)
0169 #define dmz_is_buf(z)       test_bit(DMZ_BUF, &(z)->flags)
0170 #define dmz_is_data(z)      test_bit(DMZ_DATA, &(z)->flags)
0171 
0172 #define dmz_weight(z)       ((z)->weight)
0173 
0174 /*
0175  * Message functions.
0176  */
0177 #define dmz_dev_info(dev, format, args...)  \
0178     DMINFO("(%pg): " format, (dev)->bdev, ## args)
0179 
0180 #define dmz_dev_err(dev, format, args...)   \
0181     DMERR("(%pg): " format, (dev)->bdev, ## args)
0182 
0183 #define dmz_dev_warn(dev, format, args...)  \
0184     DMWARN("(%pg): " format, (dev)->bdev, ## args)
0185 
0186 #define dmz_dev_debug(dev, format, args...) \
0187     DMDEBUG("(%pg): " format, (dev)->bdev, ## args)
0188 
0189 /*
0190  * Functions defined in dm-zoned-metadata.c
0191  */
0192 int dmz_ctr_metadata(struct dmz_dev *dev, int num_dev,
0193              struct dmz_metadata **zmd, const char *devname);
0194 void dmz_dtr_metadata(struct dmz_metadata *zmd);
0195 int dmz_resume_metadata(struct dmz_metadata *zmd);
0196 
0197 void dmz_lock_map(struct dmz_metadata *zmd);
0198 void dmz_unlock_map(struct dmz_metadata *zmd);
0199 void dmz_lock_metadata(struct dmz_metadata *zmd);
0200 void dmz_unlock_metadata(struct dmz_metadata *zmd);
0201 void dmz_lock_flush(struct dmz_metadata *zmd);
0202 void dmz_unlock_flush(struct dmz_metadata *zmd);
0203 int dmz_flush_metadata(struct dmz_metadata *zmd);
0204 const char *dmz_metadata_label(struct dmz_metadata *zmd);
0205 
0206 sector_t dmz_start_sect(struct dmz_metadata *zmd, struct dm_zone *zone);
0207 sector_t dmz_start_block(struct dmz_metadata *zmd, struct dm_zone *zone);
0208 unsigned int dmz_nr_chunks(struct dmz_metadata *zmd);
0209 
0210 bool dmz_check_dev(struct dmz_metadata *zmd);
0211 bool dmz_dev_is_dying(struct dmz_metadata *zmd);
0212 
0213 #define DMZ_ALLOC_RND       0x01
0214 #define DMZ_ALLOC_CACHE     0x02
0215 #define DMZ_ALLOC_SEQ       0x04
0216 #define DMZ_ALLOC_RECLAIM   0x10
0217 
0218 struct dm_zone *dmz_alloc_zone(struct dmz_metadata *zmd,
0219                    unsigned int dev_idx, unsigned long flags);
0220 void dmz_free_zone(struct dmz_metadata *zmd, struct dm_zone *zone);
0221 
0222 void dmz_map_zone(struct dmz_metadata *zmd, struct dm_zone *zone,
0223           unsigned int chunk);
0224 void dmz_unmap_zone(struct dmz_metadata *zmd, struct dm_zone *zone);
0225 unsigned int dmz_nr_zones(struct dmz_metadata *zmd);
0226 unsigned int dmz_nr_cache_zones(struct dmz_metadata *zmd);
0227 unsigned int dmz_nr_unmap_cache_zones(struct dmz_metadata *zmd);
0228 unsigned int dmz_nr_rnd_zones(struct dmz_metadata *zmd, int idx);
0229 unsigned int dmz_nr_unmap_rnd_zones(struct dmz_metadata *zmd, int idx);
0230 unsigned int dmz_nr_seq_zones(struct dmz_metadata *zmd, int idx);
0231 unsigned int dmz_nr_unmap_seq_zones(struct dmz_metadata *zmd, int idx);
0232 unsigned int dmz_zone_nr_blocks(struct dmz_metadata *zmd);
0233 unsigned int dmz_zone_nr_blocks_shift(struct dmz_metadata *zmd);
0234 unsigned int dmz_zone_nr_sectors(struct dmz_metadata *zmd);
0235 unsigned int dmz_zone_nr_sectors_shift(struct dmz_metadata *zmd);
0236 
0237 /*
0238  * Activate a zone (increment its reference count).
0239  */
0240 static inline void dmz_activate_zone(struct dm_zone *zone)
0241 {
0242     atomic_inc(&zone->refcount);
0243 }
0244 
0245 int dmz_lock_zone_reclaim(struct dm_zone *zone);
0246 void dmz_unlock_zone_reclaim(struct dm_zone *zone);
0247 struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd,
0248                      unsigned int dev_idx, bool idle);
0249 
0250 struct dm_zone *dmz_get_chunk_mapping(struct dmz_metadata *zmd,
0251                       unsigned int chunk, enum req_op op);
0252 void dmz_put_chunk_mapping(struct dmz_metadata *zmd, struct dm_zone *zone);
0253 struct dm_zone *dmz_get_chunk_buffer(struct dmz_metadata *zmd,
0254                      struct dm_zone *dzone);
0255 
0256 int dmz_validate_blocks(struct dmz_metadata *zmd, struct dm_zone *zone,
0257             sector_t chunk_block, unsigned int nr_blocks);
0258 int dmz_invalidate_blocks(struct dmz_metadata *zmd, struct dm_zone *zone,
0259               sector_t chunk_block, unsigned int nr_blocks);
0260 int dmz_block_valid(struct dmz_metadata *zmd, struct dm_zone *zone,
0261             sector_t chunk_block);
0262 int dmz_first_valid_block(struct dmz_metadata *zmd, struct dm_zone *zone,
0263               sector_t *chunk_block);
0264 int dmz_copy_valid_blocks(struct dmz_metadata *zmd, struct dm_zone *from_zone,
0265               struct dm_zone *to_zone);
0266 int dmz_merge_valid_blocks(struct dmz_metadata *zmd, struct dm_zone *from_zone,
0267                struct dm_zone *to_zone, sector_t chunk_block);
0268 
0269 /*
0270  * Functions defined in dm-zoned-reclaim.c
0271  */
0272 int dmz_ctr_reclaim(struct dmz_metadata *zmd, struct dmz_reclaim **zrc, int idx);
0273 void dmz_dtr_reclaim(struct dmz_reclaim *zrc);
0274 void dmz_suspend_reclaim(struct dmz_reclaim *zrc);
0275 void dmz_resume_reclaim(struct dmz_reclaim *zrc);
0276 void dmz_reclaim_bio_acc(struct dmz_reclaim *zrc);
0277 void dmz_schedule_reclaim(struct dmz_reclaim *zrc);
0278 
0279 /*
0280  * Functions defined in dm-zoned-target.c
0281  */
0282 bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev);
0283 bool dmz_check_bdev(struct dmz_dev *dmz_dev);
0284 
0285 /*
0286  * Deactivate a zone. This decrement the zone reference counter
0287  * indicating that all BIOs to the zone have completed when the count is 0.
0288  */
0289 static inline void dmz_deactivate_zone(struct dm_zone *zone)
0290 {
0291     dmz_reclaim_bio_acc(zone->dev->reclaim);
0292     atomic_dec(&zone->refcount);
0293 }
0294 
0295 /*
0296  * Test if a zone is active, that is, has a refcount > 0.
0297  */
0298 static inline bool dmz_is_active(struct dm_zone *zone)
0299 {
0300     return atomic_read(&zone->refcount);
0301 }
0302 
0303 #endif /* DM_ZONED_H */