From ad83cfe2cced9d29d6a5945ddfa13ffe8bbe84aa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Mar 2017 23:03:53 +0900 Subject: [PATCH] 4.9-stable patches added patches: dm-flush-queued-bios-when-process-blocks-to-avoid-deadlock.patch ext4-don-t-bug-when-truncating-encrypted-inodes-on-the-orphan-list.patch ib-mlx5-verify-that-q-counters-are-supported.patch rc-raw-decoder-for-keymap-protocol-is-not-loaded-on-register.patch --- ...hen-process-blocks-to-avoid-deadlock.patch | 122 ++++++++++++++++++ ...-encrypted-inodes-on-the-orphan-list.patch | 100 ++++++++++++++ ...verify-that-q-counters-are-supported.patch | 62 +++++++++ ...p-protocol-is-not-loaded-on-register.patch | 54 ++++++++ queue-4.9/series | 4 + 5 files changed, 342 insertions(+) create mode 100644 queue-4.9/dm-flush-queued-bios-when-process-blocks-to-avoid-deadlock.patch create mode 100644 queue-4.9/ext4-don-t-bug-when-truncating-encrypted-inodes-on-the-orphan-list.patch create mode 100644 queue-4.9/ib-mlx5-verify-that-q-counters-are-supported.patch create mode 100644 queue-4.9/rc-raw-decoder-for-keymap-protocol-is-not-loaded-on-register.patch diff --git a/queue-4.9/dm-flush-queued-bios-when-process-blocks-to-avoid-deadlock.patch b/queue-4.9/dm-flush-queued-bios-when-process-blocks-to-avoid-deadlock.patch new file mode 100644 index 00000000000..7c3d0c69c47 --- /dev/null +++ b/queue-4.9/dm-flush-queued-bios-when-process-blocks-to-avoid-deadlock.patch @@ -0,0 +1,122 @@ +From d67a5f4b5947aba4bfe9a80a2b86079c215ca755 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 15 Feb 2017 11:26:10 -0500 +Subject: dm: flush queued bios when process blocks to avoid deadlock + +From: Mikulas Patocka + +commit d67a5f4b5947aba4bfe9a80a2b86079c215ca755 upstream. + +Commit df2cb6daa4 ("block: Avoid deadlocks with bio allocation by +stacking drivers") created a workqueue for every bio set and code +in bio_alloc_bioset() that tries to resolve some low-memory deadlocks +by redirecting bios queued on current->bio_list to the workqueue if the +system is low on memory. However other deadlocks (see below **) may +happen, without any low memory condition, because generic_make_request +is queuing bios to current->bio_list (rather than submitting them). + +** the related dm-snapshot deadlock is detailed here: +https://www.redhat.com/archives/dm-devel/2016-July/msg00065.html + +Fix this deadlock by redirecting any bios on current->bio_list to the +bio_set's rescue workqueue on every schedule() call. Consequently, +when the process blocks on a mutex, the bios queued on +current->bio_list are dispatched to independent workqueus and they can +complete without waiting for the mutex to be available. + +The structure blk_plug contains an entry cb_list and this list can contain +arbitrary callback functions that are called when the process blocks. +To implement this fix DM (ab)uses the onstack plug's cb_list interface +to get its flush_current_bio_list() called at schedule() time. + +This fixes the snapshot deadlock - if the map method blocks, +flush_current_bio_list() will be called and it redirects bios waiting +on current->bio_list to appropriate workqueues. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1267650 +Depends-on: df2cb6daa4 ("block: Avoid deadlocks with bio allocation by stacking drivers") +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/md/dm.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -972,10 +972,61 @@ void dm_accept_partial_bio(struct bio *b + } + EXPORT_SYMBOL_GPL(dm_accept_partial_bio); + ++/* ++ * Flush current->bio_list when the target map method blocks. ++ * This fixes deadlocks in snapshot and possibly in other targets. ++ */ ++struct dm_offload { ++ struct blk_plug plug; ++ struct blk_plug_cb cb; ++}; ++ ++static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule) ++{ ++ struct dm_offload *o = container_of(cb, struct dm_offload, cb); ++ struct bio_list list; ++ struct bio *bio; ++ ++ INIT_LIST_HEAD(&o->cb.list); ++ ++ if (unlikely(!current->bio_list)) ++ return; ++ ++ list = *current->bio_list; ++ bio_list_init(current->bio_list); ++ ++ while ((bio = bio_list_pop(&list))) { ++ struct bio_set *bs = bio->bi_pool; ++ if (unlikely(!bs) || bs == fs_bio_set) { ++ bio_list_add(current->bio_list, bio); ++ continue; ++ } ++ ++ spin_lock(&bs->rescue_lock); ++ bio_list_add(&bs->rescue_list, bio); ++ queue_work(bs->rescue_workqueue, &bs->rescue_work); ++ spin_unlock(&bs->rescue_lock); ++ } ++} ++ ++static void dm_offload_start(struct dm_offload *o) ++{ ++ blk_start_plug(&o->plug); ++ o->cb.callback = flush_current_bio_list; ++ list_add(&o->cb.list, ¤t->plug->cb_list); ++} ++ ++static void dm_offload_end(struct dm_offload *o) ++{ ++ list_del(&o->cb.list); ++ blk_finish_plug(&o->plug); ++} ++ + static void __map_bio(struct dm_target_io *tio) + { + int r; + sector_t sector; ++ struct dm_offload o; + struct bio *clone = &tio->clone; + struct dm_target *ti = tio->ti; + +@@ -988,7 +1039,11 @@ static void __map_bio(struct dm_target_i + */ + atomic_inc(&tio->io->io_count); + sector = clone->bi_iter.bi_sector; ++ ++ dm_offload_start(&o); + r = ti->type->map(ti, clone); ++ dm_offload_end(&o); ++ + if (r == DM_MAPIO_REMAPPED) { + /* the bio has been remapped so dispatch it */ + diff --git a/queue-4.9/ext4-don-t-bug-when-truncating-encrypted-inodes-on-the-orphan-list.patch b/queue-4.9/ext4-don-t-bug-when-truncating-encrypted-inodes-on-the-orphan-list.patch new file mode 100644 index 00000000000..968d6ec2fe7 --- /dev/null +++ b/queue-4.9/ext4-don-t-bug-when-truncating-encrypted-inodes-on-the-orphan-list.patch @@ -0,0 +1,100 @@ +From 0d06863f903ac5f4f6efb0273079d27de3e53a28 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 14 Feb 2017 11:31:15 -0500 +Subject: ext4: don't BUG when truncating encrypted inodes on the orphan list + +From: Theodore Ts'o + +commit 0d06863f903ac5f4f6efb0273079d27de3e53a28 upstream. + +Fix a BUG when the kernel tries to mount a file system constructed as +follows: + +echo foo > foo.txt +mke2fs -Fq -t ext4 -O encrypt foo.img 100 +debugfs -w foo.img << EOF +write foo.txt a +set_inode_field a i_flags 0x80800 +set_super_value s_last_orphan 12 +quit +EOF + +root@kvm-xfstests:~# mount -o loop foo.img /mnt +[ 160.238770] ------------[ cut here ]------------ +[ 160.240106] kernel BUG at /usr/projects/linux/ext4/fs/ext4/inode.c:3874! +[ 160.240106] invalid opcode: 0000 [#1] SMP +[ 160.240106] Modules linked in: +[ 160.240106] CPU: 0 PID: 2547 Comm: mount Tainted: G W 4.10.0-rc3-00034-gcdd33b941b67 #227 +[ 160.240106] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1 04/01/2014 +[ 160.240106] task: f4518000 task.stack: f47b6000 +[ 160.240106] EIP: ext4_block_zero_page_range+0x1a7/0x2b4 +[ 160.240106] EFLAGS: 00010246 CPU: 0 +[ 160.240106] EAX: 00000001 EBX: f7be4b50 ECX: f47b7dc0 EDX: 00000007 +[ 160.240106] ESI: f43b05a8 EDI: f43babec EBP: f47b7dd0 ESP: f47b7dac +[ 160.240106] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 +[ 160.240106] CR0: 80050033 CR2: bfd85b08 CR3: 34a00680 CR4: 000006f0 +[ 160.240106] Call Trace: +[ 160.240106] ext4_truncate+0x1e9/0x3e5 +[ 160.240106] ext4_fill_super+0x286f/0x2b1e +[ 160.240106] ? set_blocksize+0x2e/0x7e +[ 160.240106] mount_bdev+0x114/0x15f +[ 160.240106] ext4_mount+0x15/0x17 +[ 160.240106] ? ext4_calculate_overhead+0x39d/0x39d +[ 160.240106] mount_fs+0x58/0x115 +[ 160.240106] vfs_kern_mount+0x4b/0xae +[ 160.240106] do_mount+0x671/0x8c3 +[ 160.240106] ? _copy_from_user+0x70/0x83 +[ 160.240106] ? strndup_user+0x31/0x46 +[ 160.240106] SyS_mount+0x57/0x7b +[ 160.240106] do_int80_syscall_32+0x4f/0x61 +[ 160.240106] entry_INT80_32+0x2f/0x2f +[ 160.240106] EIP: 0xb76b919e +[ 160.240106] EFLAGS: 00000246 CPU: 0 +[ 160.240106] EAX: ffffffda EBX: 08053838 ECX: 08052188 EDX: 080537e8 +[ 160.240106] ESI: c0ed0000 EDI: 00000000 EBP: 080537e8 ESP: bfa13660 +[ 160.240106] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b +[ 160.240106] Code: 59 8b 00 a8 01 0f 84 09 01 00 00 8b 07 66 25 00 f0 66 3d 00 80 75 61 89 f8 e8 3e e2 ff ff 84 c0 74 56 83 bf 48 02 00 00 00 75 02 <0f> 0b 81 7d e8 00 10 00 00 74 02 0f 0b 8b 43 04 8b 53 08 31 c9 +[ 160.240106] EIP: ext4_block_zero_page_range+0x1a7/0x2b4 SS:ESP: 0068:f47b7dac +[ 160.317241] ---[ end trace d6a773a375c810a5 ]--- + +The problem is that when the kernel tries to truncate an inode in +ext4_truncate(), it tries to clear any on-disk data beyond i_size. +Without the encryption key, it can't do that, and so it triggers a +BUG. + +E2fsck does *not* provide this service, and in practice most file +systems have their orphan list processed by e2fsck, so to avoid +crashing, this patch skips this step if we don't have access to the +encryption key (which is the case when processing the orphan list; in +all other cases, we will have the encryption key, or the kernel +wouldn't have allowed the file to be opened). + +An open question is whether the fact that e2fsck isn't clearing the +bytes beyond i_size causing problems --- and if we've lived with it +not doing it for so long, can we drop this from the kernel replay of +the orphan list in all cases (not just when we don't have the key for +encrypted inodes). + +Addresses-Google-Bug: #35209576 + +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3824,6 +3824,10 @@ static int ext4_block_truncate_page(hand + unsigned blocksize; + struct inode *inode = mapping->host; + ++ /* If we are processing an encrypted inode during orphan list handling */ ++ if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode)) ++ return 0; ++ + blocksize = inode->i_sb->s_blocksize; + length = blocksize - (offset & (blocksize - 1)); + diff --git a/queue-4.9/ib-mlx5-verify-that-q-counters-are-supported.patch b/queue-4.9/ib-mlx5-verify-that-q-counters-are-supported.patch new file mode 100644 index 00000000000..acb0552e481 --- /dev/null +++ b/queue-4.9/ib-mlx5-verify-that-q-counters-are-supported.patch @@ -0,0 +1,62 @@ +From 45bded2c216da6010184ac5ebe88c27f73439009 Mon Sep 17 00:00:00 2001 +From: Kamal Heib +Date: Wed, 18 Jan 2017 14:10:32 +0200 +Subject: IB/mlx5: Verify that Q counters are supported + +From: Kamal Heib + +commit 45bded2c216da6010184ac5ebe88c27f73439009 upstream. + +Make sure that the Q counters are supported by the FW before trying +to allocate/deallocte them, this will avoid driver load failure when +they aren't supported by the FW. + +Fixes: 0837e86a7a34 ('IB/mlx5: Add per port counters') +Signed-off-by: Kamal Heib +Reviewed-by: Mark Bloch +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/infiniband/hw/mlx5/main.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -3141,9 +3141,11 @@ static void *mlx5_ib_add(struct mlx5_cor + if (err) + goto err_rsrc; + +- err = mlx5_ib_alloc_q_counters(dev); +- if (err) +- goto err_odp; ++ if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) { ++ err = mlx5_ib_alloc_q_counters(dev); ++ if (err) ++ goto err_odp; ++ } + + err = ib_register_device(&dev->ib_dev, NULL); + if (err) +@@ -3171,7 +3173,8 @@ err_dev: + ib_unregister_device(&dev->ib_dev); + + err_q_cnt: +- mlx5_ib_dealloc_q_counters(dev); ++ if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) ++ mlx5_ib_dealloc_q_counters(dev); + + err_odp: + mlx5_ib_odp_remove_one(dev); +@@ -3201,7 +3204,8 @@ static void mlx5_ib_remove(struct mlx5_c + + mlx5_remove_roce_notifier(dev); + ib_unregister_device(&dev->ib_dev); +- mlx5_ib_dealloc_q_counters(dev); ++ if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) ++ mlx5_ib_dealloc_q_counters(dev); + destroy_umrc_res(dev); + mlx5_ib_odp_remove_one(dev); + destroy_dev_resources(&dev->devr); diff --git a/queue-4.9/rc-raw-decoder-for-keymap-protocol-is-not-loaded-on-register.patch b/queue-4.9/rc-raw-decoder-for-keymap-protocol-is-not-loaded-on-register.patch new file mode 100644 index 00000000000..ee3efe00b5c --- /dev/null +++ b/queue-4.9/rc-raw-decoder-for-keymap-protocol-is-not-loaded-on-register.patch @@ -0,0 +1,54 @@ +From 413808685dd7c9b54bbc5af79da2eaddd0fc3cb2 Mon Sep 17 00:00:00 2001 +From: Sean Young +Date: Wed, 22 Feb 2017 18:48:01 -0300 +Subject: [media] rc: raw decoder for keymap protocol is not loaded on register + +From: Sean Young + +commit 413808685dd7c9b54bbc5af79da2eaddd0fc3cb2 upstream. + +When the protocol is set via the sysfs protocols attribute, the +decoder is loaded. However, when it is not when a device is first +plugged in or registered. + +Fixes: acc1c3c ("[media] media: rc: load decoder modules on-demand") + +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/media/rc/rc-main.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/media/rc/rc-main.c ++++ b/drivers/media/rc/rc-main.c +@@ -1411,6 +1411,7 @@ int rc_register_device(struct rc_dev *de + int attr = 0; + int minor; + int rc; ++ u64 rc_type; + + if (!dev || !dev->map_name) + return -EINVAL; +@@ -1496,14 +1497,18 @@ int rc_register_device(struct rc_dev *de + goto out_input; + } + ++ rc_type = BIT_ULL(rc_map->rc_type); ++ + if (dev->change_protocol) { +- u64 rc_type = (1ll << rc_map->rc_type); + rc = dev->change_protocol(dev, &rc_type); + if (rc < 0) + goto out_raw; + dev->enabled_protocols = rc_type; + } + ++ if (dev->driver_type == RC_DRIVER_IR_RAW) ++ ir_raw_load_modules(&rc_type); ++ + /* Allow the RC sysfs nodes to be accessible */ + atomic_set(&dev->initialized, 1); + diff --git a/queue-4.9/series b/queue-4.9/series index dc22ddd0850..5623db2f294 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -38,3 +38,7 @@ usb-serial-io_ti-fix-information-leak-in-completion-handler.patch serial-samsung-continue-to-work-if-dma-request-fails.patch kvm-s390-fix-guest-migration-for-huge-guests-resulting-in-panic.patch kvm-arm-arm64-let-vcpu-thread-modify-its-own-active-state.patch +dm-flush-queued-bios-when-process-blocks-to-avoid-deadlock.patch +rc-raw-decoder-for-keymap-protocol-is-not-loaded-on-register.patch +ext4-don-t-bug-when-truncating-encrypted-inodes-on-the-orphan-list.patch +ib-mlx5-verify-that-q-counters-are-supported.patch -- 2.47.3