Skip to content

Commit 43f4d36

Browse files
committed
Merge tag 'dm-4.8-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: - a stable fix for DM round robin multipath path selector to disable preemption before using this_cpu_ptr() - a slight increase in DM crypt's mempool reserves to make swap ontop of DM crypt more performant - a few DM raid fixes to issues found while testing changes that were merged in v4.8-rc1 * tag 'dm-4.8-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm raid: support raid0 with missing metadata devices dm raid: enhance attempt_restore_of_faulty_devices() to support more devices dm raid: fix restoring of failed devices regression dm raid: fix frozen recovery regression dm crypt: increase mempool reserve to better support swapping dm round robin: do not use this_cpu_ptr() without having preemption disabled
2 parents b284879 + 9e7d936 commit 43f4d36

File tree

3 files changed

+53
-38
lines changed

3 files changed

+53
-38
lines changed

drivers/md/dm-crypt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ struct crypt_config {
181181
u8 key[0];
182182
};
183183

184-
#define MIN_IOS 16
184+
#define MIN_IOS 64
185185

186186
static void clone_init(struct dm_crypt_io *, struct bio *);
187187
static void kcryptd_queue_crypt(struct dm_crypt_io *io);

drivers/md/dm-raid.c

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ struct raid_dev {
191191
#define RT_FLAG_RS_BITMAP_LOADED 2
192192
#define RT_FLAG_UPDATE_SBS 3
193193
#define RT_FLAG_RESHAPE_RS 4
194-
#define RT_FLAG_KEEP_RS_FROZEN 5
195194

196195
/* Array elements of 64 bit needed for rebuild/failed disk bits */
197196
#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8)
@@ -861,6 +860,9 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
861860
{
862861
unsigned long min_region_size = rs->ti->len / (1 << 21);
863862

863+
if (rs_is_raid0(rs))
864+
return 0;
865+
864866
if (!region_size) {
865867
/*
866868
* Choose a reasonable default. All figures in sectors.
@@ -930,6 +932,8 @@ static int validate_raid_redundancy(struct raid_set *rs)
930932
rebuild_cnt++;
931933

932934
switch (rs->raid_type->level) {
935+
case 0:
936+
break;
933937
case 1:
934938
if (rebuild_cnt >= rs->md.raid_disks)
935939
goto too_many;
@@ -2335,6 +2339,13 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
23352339
case 0:
23362340
break;
23372341
default:
2342+
/*
2343+
* We have to keep any raid0 data/metadata device pairs or
2344+
* the MD raid0 personality will fail to start the array.
2345+
*/
2346+
if (rs_is_raid0(rs))
2347+
continue;
2348+
23382349
dev = container_of(rdev, struct raid_dev, rdev);
23392350
if (dev->meta_dev)
23402351
dm_put_device(ti, dev->meta_dev);
@@ -2579,7 +2590,6 @@ static int rs_prepare_reshape(struct raid_set *rs)
25792590
} else {
25802591
/* Process raid1 without delta_disks */
25812592
mddev->raid_disks = rs->raid_disks;
2582-
set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
25832593
reshape = false;
25842594
}
25852595
} else {
@@ -2590,7 +2600,6 @@ static int rs_prepare_reshape(struct raid_set *rs)
25902600
if (reshape) {
25912601
set_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags);
25922602
set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2593-
set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
25942603
} else if (mddev->raid_disks < rs->raid_disks)
25952604
/* Create new superblocks and bitmaps, if any new disks */
25962605
set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
@@ -2902,7 +2911,6 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
29022911
goto bad;
29032912

29042913
set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
2905-
set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
29062914
/* Takeover ain't recovery, so disable recovery */
29072915
rs_setup_recovery(rs, MaxSector);
29082916
rs_set_new(rs);
@@ -3386,21 +3394,28 @@ static void raid_postsuspend(struct dm_target *ti)
33863394
{
33873395
struct raid_set *rs = ti->private;
33883396

3389-
if (test_and_clear_bit(RT_FLAG_RS_RESUMED, &rs->runtime_flags)) {
3390-
if (!rs->md.suspended)
3391-
mddev_suspend(&rs->md);
3392-
rs->md.ro = 1;
3393-
}
3397+
if (!rs->md.suspended)
3398+
mddev_suspend(&rs->md);
3399+
3400+
rs->md.ro = 1;
33943401
}
33953402

33963403
static void attempt_restore_of_faulty_devices(struct raid_set *rs)
33973404
{
33983405
int i;
3399-
uint64_t failed_devices, cleared_failed_devices = 0;
3406+
uint64_t cleared_failed_devices[DISKS_ARRAY_ELEMS];
34003407
unsigned long flags;
3408+
bool cleared = false;
34013409
struct dm_raid_superblock *sb;
3410+
struct mddev *mddev = &rs->md;
34023411
struct md_rdev *r;
34033412

3413+
/* RAID personalities have to provide hot add/remove methods or we need to bail out. */
3414+
if (!mddev->pers || !mddev->pers->hot_add_disk || !mddev->pers->hot_remove_disk)
3415+
return;
3416+
3417+
memset(cleared_failed_devices, 0, sizeof(cleared_failed_devices));
3418+
34043419
for (i = 0; i < rs->md.raid_disks; i++) {
34053420
r = &rs->dev[i].rdev;
34063421
if (test_bit(Faulty, &r->flags) && r->sb_page &&
@@ -3420,7 +3435,7 @@ static void attempt_restore_of_faulty_devices(struct raid_set *rs)
34203435
* ourselves.
34213436
*/
34223437
if ((r->raid_disk >= 0) &&
3423-
(r->mddev->pers->hot_remove_disk(r->mddev, r) != 0))
3438+
(mddev->pers->hot_remove_disk(mddev, r) != 0))
34243439
/* Failed to revive this device, try next */
34253440
continue;
34263441

@@ -3430,22 +3445,30 @@ static void attempt_restore_of_faulty_devices(struct raid_set *rs)
34303445
clear_bit(Faulty, &r->flags);
34313446
clear_bit(WriteErrorSeen, &r->flags);
34323447
clear_bit(In_sync, &r->flags);
3433-
if (r->mddev->pers->hot_add_disk(r->mddev, r)) {
3448+
if (mddev->pers->hot_add_disk(mddev, r)) {
34343449
r->raid_disk = -1;
34353450
r->saved_raid_disk = -1;
34363451
r->flags = flags;
34373452
} else {
34383453
r->recovery_offset = 0;
3439-
cleared_failed_devices |= 1 << i;
3454+
set_bit(i, (void *) cleared_failed_devices);
3455+
cleared = true;
34403456
}
34413457
}
34423458
}
3443-
if (cleared_failed_devices) {
3459+
3460+
/* If any failed devices could be cleared, update all sbs failed_devices bits */
3461+
if (cleared) {
3462+
uint64_t failed_devices[DISKS_ARRAY_ELEMS];
3463+
34443464
rdev_for_each(r, &rs->md) {
34453465
sb = page_address(r->sb_page);
3446-
failed_devices = le64_to_cpu(sb->failed_devices);
3447-
failed_devices &= ~cleared_failed_devices;
3448-
sb->failed_devices = cpu_to_le64(failed_devices);
3466+
sb_retrieve_failed_devices(sb, failed_devices);
3467+
3468+
for (i = 0; i < DISKS_ARRAY_ELEMS; i++)
3469+
failed_devices[i] &= ~cleared_failed_devices[i];
3470+
3471+
sb_update_failed_devices(sb, failed_devices);
34493472
}
34503473
}
34513474
}
@@ -3610,26 +3633,15 @@ static void raid_resume(struct dm_target *ti)
36103633
* devices are reachable again.
36113634
*/
36123635
attempt_restore_of_faulty_devices(rs);
3613-
} else {
3614-
mddev->ro = 0;
3615-
mddev->in_sync = 0;
3636+
}
36163637

3617-
/*
3618-
* When passing in flags to the ctr, we expect userspace
3619-
* to reset them because they made it to the superblocks
3620-
* and reload the mapping anyway.
3621-
*
3622-
* -> only unfreeze recovery in case of a table reload or
3623-
* we'll have a bogus recovery/reshape position
3624-
* retrieved from the superblock by the ctr because
3625-
* the ongoing recovery/reshape will change it after read.
3626-
*/
3627-
if (!test_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags))
3628-
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
3638+
mddev->ro = 0;
3639+
mddev->in_sync = 0;
36293640

3630-
if (mddev->suspended)
3631-
mddev_resume(mddev);
3632-
}
3641+
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
3642+
3643+
if (mddev->suspended)
3644+
mddev_resume(mddev);
36333645
}
36343646

36353647
static struct target_type raid_target = {

drivers/md/dm-round-robin.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,17 @@ static struct dm_path *rr_select_path(struct path_selector *ps, size_t nr_bytes)
210210
struct path_info *pi = NULL;
211211
struct dm_path *current_path = NULL;
212212

213+
local_irq_save(flags);
213214
current_path = *this_cpu_ptr(s->current_path);
214215
if (current_path) {
215216
percpu_counter_dec(&s->repeat_count);
216-
if (percpu_counter_read_positive(&s->repeat_count) > 0)
217+
if (percpu_counter_read_positive(&s->repeat_count) > 0) {
218+
local_irq_restore(flags);
217219
return current_path;
220+
}
218221
}
219222

220-
spin_lock_irqsave(&s->lock, flags);
223+
spin_lock(&s->lock);
221224
if (!list_empty(&s->valid_paths)) {
222225
pi = list_entry(s->valid_paths.next, struct path_info, list);
223226
list_move_tail(&pi->list, &s->valid_paths);

0 commit comments

Comments
 (0)