Skip to content

Commit 3bfe1fc

Browse files
committed
Merge tag 'for-5.3/dm-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull more device mapper updates from Mike Snitzer: - Fix zone state management race in DM zoned target by eliminating the unnecessary DMZ_ACTIVE state. - A couple fixes for issues the DM snapshot target's optional discard support added during first week of the 5.3 merge. - Increase default size of outstanding IO that is allowed for a each dm-kcopyd client and introduce tunable to allow user adjust. - Update DM core to use printk ratelimiting functions rather than duplicate them and in doing so fix an issue where DMDEBUG_LIMIT() rate limited KERN_DEBUG messages had excessive "callbacks suppressed" messages. * tag 'for-5.3/dm-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm: use printk ratelimiting functions dm kcopyd: Increase default sub-job size to 512KB dm snapshot: fix oversights in optional discard support dm zoned: fix zone state management race
2 parents 6860c98 + 733232f commit 3bfe1fc

File tree

5 files changed

+66
-47
lines changed

5 files changed

+66
-47
lines changed

drivers/md/dm-kcopyd.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,27 @@
2828

2929
#include "dm-core.h"
3030

31-
#define SUB_JOB_SIZE 128
3231
#define SPLIT_COUNT 8
3332
#define MIN_JOBS 8
34-
#define RESERVE_PAGES (DIV_ROUND_UP(SUB_JOB_SIZE << SECTOR_SHIFT, PAGE_SIZE))
33+
34+
#define DEFAULT_SUB_JOB_SIZE_KB 512
35+
#define MAX_SUB_JOB_SIZE_KB 1024
36+
37+
static unsigned kcopyd_subjob_size_kb = DEFAULT_SUB_JOB_SIZE_KB;
38+
39+
module_param(kcopyd_subjob_size_kb, uint, S_IRUGO | S_IWUSR);
40+
MODULE_PARM_DESC(kcopyd_subjob_size_kb, "Sub-job size for dm-kcopyd clients");
41+
42+
static unsigned dm_get_kcopyd_subjob_size(void)
43+
{
44+
unsigned sub_job_size_kb;
45+
46+
sub_job_size_kb = __dm_get_module_param(&kcopyd_subjob_size_kb,
47+
DEFAULT_SUB_JOB_SIZE_KB,
48+
MAX_SUB_JOB_SIZE_KB);
49+
50+
return sub_job_size_kb << 1;
51+
}
3552

3653
/*-----------------------------------------------------------------
3754
* Each kcopyd client has its own little pool of preallocated
@@ -41,6 +58,7 @@ struct dm_kcopyd_client {
4158
struct page_list *pages;
4259
unsigned nr_reserved_pages;
4360
unsigned nr_free_pages;
61+
unsigned sub_job_size;
4462

4563
struct dm_io_client *io_client;
4664

@@ -693,8 +711,8 @@ static void segment_complete(int read_err, unsigned long write_err,
693711
progress = job->progress;
694712
count = job->source.count - progress;
695713
if (count) {
696-
if (count > SUB_JOB_SIZE)
697-
count = SUB_JOB_SIZE;
714+
if (count > kc->sub_job_size)
715+
count = kc->sub_job_size;
698716

699717
job->progress += count;
700718
}
@@ -821,7 +839,7 @@ void dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
821839
job->master_job = job;
822840
job->write_offset = 0;
823841

824-
if (job->source.count <= SUB_JOB_SIZE)
842+
if (job->source.count <= kc->sub_job_size)
825843
dispatch_job(job);
826844
else {
827845
job->progress = 0;
@@ -888,6 +906,7 @@ int kcopyd_cancel(struct kcopyd_job *job, int block)
888906
struct dm_kcopyd_client *dm_kcopyd_client_create(struct dm_kcopyd_throttle *throttle)
889907
{
890908
int r;
909+
unsigned reserve_pages;
891910
struct dm_kcopyd_client *kc;
892911

893912
kc = kzalloc(sizeof(*kc), GFP_KERNEL);
@@ -912,9 +931,12 @@ struct dm_kcopyd_client *dm_kcopyd_client_create(struct dm_kcopyd_throttle *thro
912931
goto bad_workqueue;
913932
}
914933

934+
kc->sub_job_size = dm_get_kcopyd_subjob_size();
935+
reserve_pages = DIV_ROUND_UP(kc->sub_job_size << SECTOR_SHIFT, PAGE_SIZE);
936+
915937
kc->pages = NULL;
916938
kc->nr_reserved_pages = kc->nr_free_pages = 0;
917-
r = client_reserve_pages(kc, RESERVE_PAGES);
939+
r = client_reserve_pages(kc, reserve_pages);
918940
if (r)
919941
goto bad_client_pages;
920942

drivers/md/dm-snap.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,12 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
20722072
return DM_MAPIO_REMAPPED;
20732073
}
20742074

2075+
if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) {
2076+
/* Once merging, discards no longer effect change */
2077+
bio_endio(bio);
2078+
return DM_MAPIO_SUBMITTED;
2079+
}
2080+
20752081
chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector);
20762082

20772083
down_write(&s->lock);
@@ -2331,13 +2337,17 @@ static void snapshot_io_hints(struct dm_target *ti, struct queue_limits *limits)
23312337
if (snap->discard_zeroes_cow) {
23322338
struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
23332339

2340+
down_read(&_origins_lock);
2341+
23342342
(void) __find_snapshots_sharing_cow(snap, &snap_src, &snap_dest, NULL);
23352343
if (snap_src && snap_dest)
23362344
snap = snap_src;
23372345

23382346
/* All discards are split on chunk_size boundary */
23392347
limits->discard_granularity = snap->store->chunk_size;
23402348
limits->max_discard_sectors = snap->store->chunk_size;
2349+
2350+
up_read(&_origins_lock);
23412351
}
23422352
}
23432353

drivers/md/dm-zoned-metadata.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,30 +1601,6 @@ struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd)
16011601
return zone;
16021602
}
16031603

1604-
/*
1605-
* Activate a zone (increment its reference count).
1606-
*/
1607-
void dmz_activate_zone(struct dm_zone *zone)
1608-
{
1609-
set_bit(DMZ_ACTIVE, &zone->flags);
1610-
atomic_inc(&zone->refcount);
1611-
}
1612-
1613-
/*
1614-
* Deactivate a zone. This decrement the zone reference counter
1615-
* and clears the active state of the zone once the count reaches 0,
1616-
* indicating that all BIOs to the zone have completed. Returns
1617-
* true if the zone was deactivated.
1618-
*/
1619-
void dmz_deactivate_zone(struct dm_zone *zone)
1620-
{
1621-
if (atomic_dec_and_test(&zone->refcount)) {
1622-
WARN_ON(!test_bit(DMZ_ACTIVE, &zone->flags));
1623-
clear_bit_unlock(DMZ_ACTIVE, &zone->flags);
1624-
smp_mb__after_atomic();
1625-
}
1626-
}
1627-
16281604
/*
16291605
* Get the zone mapping a chunk, if the chunk is mapped already.
16301606
* If no mapping exist and the operation is WRITE, a zone is

drivers/md/dm-zoned.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ enum {
115115
DMZ_BUF,
116116

117117
/* Zone internal state */
118-
DMZ_ACTIVE,
119118
DMZ_RECLAIM,
120119
DMZ_SEQ_WRITE_ERR,
121120
};
@@ -128,7 +127,6 @@ enum {
128127
#define dmz_is_empty(z) ((z)->wp_block == 0)
129128
#define dmz_is_offline(z) test_bit(DMZ_OFFLINE, &(z)->flags)
130129
#define dmz_is_readonly(z) test_bit(DMZ_READ_ONLY, &(z)->flags)
131-
#define dmz_is_active(z) test_bit(DMZ_ACTIVE, &(z)->flags)
132130
#define dmz_in_reclaim(z) test_bit(DMZ_RECLAIM, &(z)->flags)
133131
#define dmz_seq_write_err(z) test_bit(DMZ_SEQ_WRITE_ERR, &(z)->flags)
134132

@@ -188,8 +186,30 @@ void dmz_unmap_zone(struct dmz_metadata *zmd, struct dm_zone *zone);
188186
unsigned int dmz_nr_rnd_zones(struct dmz_metadata *zmd);
189187
unsigned int dmz_nr_unmap_rnd_zones(struct dmz_metadata *zmd);
190188

191-
void dmz_activate_zone(struct dm_zone *zone);
192-
void dmz_deactivate_zone(struct dm_zone *zone);
189+
/*
190+
* Activate a zone (increment its reference count).
191+
*/
192+
static inline void dmz_activate_zone(struct dm_zone *zone)
193+
{
194+
atomic_inc(&zone->refcount);
195+
}
196+
197+
/*
198+
* Deactivate a zone. This decrement the zone reference counter
199+
* indicating that all BIOs to the zone have completed when the count is 0.
200+
*/
201+
static inline void dmz_deactivate_zone(struct dm_zone *zone)
202+
{
203+
atomic_dec(&zone->refcount);
204+
}
205+
206+
/*
207+
* Test if a zone is active, that is, has a refcount > 0.
208+
*/
209+
static inline bool dmz_is_active(struct dm_zone *zone)
210+
{
211+
return atomic_read(&zone->refcount);
212+
}
193213

194214
int dmz_lock_zone_reclaim(struct dm_zone *zone);
195215
void dmz_unlock_zone_reclaim(struct dm_zone *zone);

include/linux/device-mapper.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -529,29 +529,20 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
529529
*---------------------------------------------------------------*/
530530
#define DM_NAME "device-mapper"
531531

532-
#define DM_RATELIMIT(pr_func, fmt, ...) \
533-
do { \
534-
static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, \
535-
DEFAULT_RATELIMIT_BURST); \
536-
\
537-
if (__ratelimit(&rs)) \
538-
pr_func(DM_FMT(fmt), ##__VA_ARGS__); \
539-
} while (0)
540-
541532
#define DM_FMT(fmt) DM_NAME ": " DM_MSG_PREFIX ": " fmt "\n"
542533

543534
#define DMCRIT(fmt, ...) pr_crit(DM_FMT(fmt), ##__VA_ARGS__)
544535

545536
#define DMERR(fmt, ...) pr_err(DM_FMT(fmt), ##__VA_ARGS__)
546-
#define DMERR_LIMIT(fmt, ...) DM_RATELIMIT(pr_err, fmt, ##__VA_ARGS__)
537+
#define DMERR_LIMIT(fmt, ...) pr_err_ratelimited(DM_FMT(fmt), ##__VA_ARGS__)
547538
#define DMWARN(fmt, ...) pr_warn(DM_FMT(fmt), ##__VA_ARGS__)
548-
#define DMWARN_LIMIT(fmt, ...) DM_RATELIMIT(pr_warn, fmt, ##__VA_ARGS__)
539+
#define DMWARN_LIMIT(fmt, ...) pr_warn_ratelimited(DM_FMT(fmt), ##__VA_ARGS__)
549540
#define DMINFO(fmt, ...) pr_info(DM_FMT(fmt), ##__VA_ARGS__)
550-
#define DMINFO_LIMIT(fmt, ...) DM_RATELIMIT(pr_info, fmt, ##__VA_ARGS__)
541+
#define DMINFO_LIMIT(fmt, ...) pr_info_ratelimited(DM_FMT(fmt), ##__VA_ARGS__)
551542

552543
#ifdef CONFIG_DM_DEBUG
553544
#define DMDEBUG(fmt, ...) printk(KERN_DEBUG DM_FMT(fmt), ##__VA_ARGS__)
554-
#define DMDEBUG_LIMIT(fmt, ...) DM_RATELIMIT(pr_debug, fmt, ##__VA_ARGS__)
545+
#define DMDEBUG_LIMIT(fmt, ...) pr_debug_ratelimited(DM_FMT(fmt), ##__VA_ARGS__)
555546
#else
556547
#define DMDEBUG(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
557548
#define DMDEBUG_LIMIT(fmt, ...) no_printk(fmt, ##__VA_ARGS__)

0 commit comments

Comments
 (0)