--- /dev/null
+From feb92d7d3813456c11dce215b3421801a78a8986 Mon Sep 17 00:00:00 2001
+From: Vineet Gupta <vgupta@synopsys.com>
+Date: Sun, 26 Jul 2020 21:51:59 -0700
+Subject: ARC: perf: don't bail setup if pct irq missing in device-tree
+
+From: Vineet Gupta <vgupta@synopsys.com>
+
+commit feb92d7d3813456c11dce215b3421801a78a8986 upstream.
+
+Current code inadventely bails if hardware supports sampling/overflow
+interrupts, but the irq is missing from device tree.
+
+|
+| # perf stat -e cycles,instructions,major-faults,minor-faults ../hackbench
+| Running with 10 groups 400 process
+| Time: 0.921
+|
+| Performance counter stats for '../hackbench':
+|
+| <not supported> cycles
+| <not supported> instructions
+| 0 major-faults
+| 8679 minor-faults
+
+This need not be as we can still do simple counting based perf stat.
+This unborks perf on HSDK-4xD
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/kernel/perf_event.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/arch/arc/kernel/perf_event.c
++++ b/arch/arc/kernel/perf_event.c
+@@ -562,7 +562,7 @@ static int arc_pmu_device_probe(struct p
+ {
+ struct arc_reg_pct_build pct_bcr;
+ struct arc_reg_cc_build cc_bcr;
+- int i, has_interrupts;
++ int i, has_interrupts, irq;
+ int counter_size; /* in bits */
+
+ union cc_name {
+@@ -637,13 +637,7 @@ static int arc_pmu_device_probe(struct p
+ .attr_groups = arc_pmu->attr_groups,
+ };
+
+- if (has_interrupts) {
+- int irq = platform_get_irq(pdev, 0);
+-
+- if (irq < 0) {
+- pr_err("Cannot get IRQ number for the platform\n");
+- return -ENODEV;
+- }
++ if (has_interrupts && (irq = platform_get_irq(pdev, 0) >= 0)) {
+
+ arc_pmu->irq = irq;
+
+@@ -652,9 +646,9 @@ static int arc_pmu_device_probe(struct p
+ this_cpu_ptr(&arc_pmu_cpu));
+
+ on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
+-
+- } else
++ } else {
+ arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
++ }
+
+ /*
+ * perf parser doesn't really like '-' symbol in events name, so let's
--- /dev/null
+From e89c4a9c8e6ce3a84cab4f342687d3fbbb1234eb Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:29 -0400
+Subject: btrfs: allocate scrub workqueues outside of locks
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit e89c4a9c8e6ce3a84cab4f342687d3fbbb1234eb upstream.
+
+I got the following lockdep splat while testing:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.8.0-rc7-00172-g021118712e59 #932 Not tainted
+ ------------------------------------------------------
+ btrfs/229626 is trying to acquire lock:
+ ffffffff828513f0 (cpu_hotplug_lock){++++}-{0:0}, at: alloc_workqueue+0x378/0x450
+
+ but task is already holding lock:
+ ffff889dd3889518 (&fs_info->scrub_lock){+.+.}-{3:3}, at: btrfs_scrub_dev+0x11c/0x630
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #7 (&fs_info->scrub_lock){+.+.}-{3:3}:
+ __mutex_lock+0x9f/0x930
+ btrfs_scrub_dev+0x11c/0x630
+ btrfs_dev_replace_by_ioctl.cold.21+0x10a/0x1d4
+ btrfs_ioctl+0x2799/0x30a0
+ ksys_ioctl+0x83/0xc0
+ __x64_sys_ioctl+0x16/0x20
+ do_syscall_64+0x50/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #6 (&fs_devs->device_list_mutex){+.+.}-{3:3}:
+ __mutex_lock+0x9f/0x930
+ btrfs_run_dev_stats+0x49/0x480
+ commit_cowonly_roots+0xb5/0x2a0
+ btrfs_commit_transaction+0x516/0xa60
+ sync_filesystem+0x6b/0x90
+ generic_shutdown_super+0x22/0x100
+ kill_anon_super+0xe/0x30
+ btrfs_kill_super+0x12/0x20
+ deactivate_locked_super+0x29/0x60
+ cleanup_mnt+0xb8/0x140
+ task_work_run+0x6d/0xb0
+ __prepare_exit_to_usermode+0x1cc/0x1e0
+ do_syscall_64+0x5c/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #5 (&fs_info->tree_log_mutex){+.+.}-{3:3}:
+ __mutex_lock+0x9f/0x930
+ btrfs_commit_transaction+0x4bb/0xa60
+ sync_filesystem+0x6b/0x90
+ generic_shutdown_super+0x22/0x100
+ kill_anon_super+0xe/0x30
+ btrfs_kill_super+0x12/0x20
+ deactivate_locked_super+0x29/0x60
+ cleanup_mnt+0xb8/0x140
+ task_work_run+0x6d/0xb0
+ __prepare_exit_to_usermode+0x1cc/0x1e0
+ do_syscall_64+0x5c/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #4 (&fs_info->reloc_mutex){+.+.}-{3:3}:
+ __mutex_lock+0x9f/0x930
+ btrfs_record_root_in_trans+0x43/0x70
+ start_transaction+0xd1/0x5d0
+ btrfs_dirty_inode+0x42/0xd0
+ touch_atime+0xa1/0xd0
+ btrfs_file_mmap+0x3f/0x60
+ mmap_region+0x3a4/0x640
+ do_mmap+0x376/0x580
+ vm_mmap_pgoff+0xd5/0x120
+ ksys_mmap_pgoff+0x193/0x230
+ do_syscall_64+0x50/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #3 (&mm->mmap_lock#2){++++}-{3:3}:
+ __might_fault+0x68/0x90
+ _copy_to_user+0x1e/0x80
+ perf_read+0x141/0x2c0
+ vfs_read+0xad/0x1b0
+ ksys_read+0x5f/0xe0
+ do_syscall_64+0x50/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #2 (&cpuctx_mutex){+.+.}-{3:3}:
+ __mutex_lock+0x9f/0x930
+ perf_event_init_cpu+0x88/0x150
+ perf_event_init+0x1db/0x20b
+ start_kernel+0x3ae/0x53c
+ secondary_startup_64+0xa4/0xb0
+
+ -> #1 (pmus_lock){+.+.}-{3:3}:
+ __mutex_lock+0x9f/0x930
+ perf_event_init_cpu+0x4f/0x150
+ cpuhp_invoke_callback+0xb1/0x900
+ _cpu_up.constprop.26+0x9f/0x130
+ cpu_up+0x7b/0xc0
+ bringup_nonboot_cpus+0x4f/0x60
+ smp_init+0x26/0x71
+ kernel_init_freeable+0x110/0x258
+ kernel_init+0xa/0x103
+ ret_from_fork+0x1f/0x30
+
+ -> #0 (cpu_hotplug_lock){++++}-{0:0}:
+ __lock_acquire+0x1272/0x2310
+ lock_acquire+0x9e/0x360
+ cpus_read_lock+0x39/0xb0
+ alloc_workqueue+0x378/0x450
+ __btrfs_alloc_workqueue+0x15d/0x200
+ btrfs_alloc_workqueue+0x51/0x160
+ scrub_workers_get+0x5a/0x170
+ btrfs_scrub_dev+0x18c/0x630
+ btrfs_dev_replace_by_ioctl.cold.21+0x10a/0x1d4
+ btrfs_ioctl+0x2799/0x30a0
+ ksys_ioctl+0x83/0xc0
+ __x64_sys_ioctl+0x16/0x20
+ do_syscall_64+0x50/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ other info that might help us debug this:
+
+ Chain exists of:
+ cpu_hotplug_lock --> &fs_devs->device_list_mutex --> &fs_info->scrub_lock
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(&fs_info->scrub_lock);
+ lock(&fs_devs->device_list_mutex);
+ lock(&fs_info->scrub_lock);
+ lock(cpu_hotplug_lock);
+
+ *** DEADLOCK ***
+
+ 2 locks held by btrfs/229626:
+ #0: ffff88bfe8bb86e0 (&fs_devs->device_list_mutex){+.+.}-{3:3}, at: btrfs_scrub_dev+0xbd/0x630
+ #1: ffff889dd3889518 (&fs_info->scrub_lock){+.+.}-{3:3}, at: btrfs_scrub_dev+0x11c/0x630
+
+ stack backtrace:
+ CPU: 15 PID: 229626 Comm: btrfs Kdump: loaded Not tainted 5.8.0-rc7-00172-g021118712e59 #932
+ Hardware name: Quanta Tioga Pass Single Side 01-0030993006/Tioga Pass Single Side, BIOS F08_3A18 12/20/2018
+ Call Trace:
+ dump_stack+0x78/0xa0
+ check_noncircular+0x165/0x180
+ __lock_acquire+0x1272/0x2310
+ lock_acquire+0x9e/0x360
+ ? alloc_workqueue+0x378/0x450
+ cpus_read_lock+0x39/0xb0
+ ? alloc_workqueue+0x378/0x450
+ alloc_workqueue+0x378/0x450
+ ? rcu_read_lock_sched_held+0x52/0x80
+ __btrfs_alloc_workqueue+0x15d/0x200
+ btrfs_alloc_workqueue+0x51/0x160
+ scrub_workers_get+0x5a/0x170
+ btrfs_scrub_dev+0x18c/0x630
+ ? start_transaction+0xd1/0x5d0
+ btrfs_dev_replace_by_ioctl.cold.21+0x10a/0x1d4
+ btrfs_ioctl+0x2799/0x30a0
+ ? do_sigaction+0x102/0x250
+ ? lockdep_hardirqs_on_prepare+0xca/0x160
+ ? _raw_spin_unlock_irq+0x24/0x30
+ ? trace_hardirqs_on+0x1c/0xe0
+ ? _raw_spin_unlock_irq+0x24/0x30
+ ? do_sigaction+0x102/0x250
+ ? ksys_ioctl+0x83/0xc0
+ ksys_ioctl+0x83/0xc0
+ __x64_sys_ioctl+0x16/0x20
+ do_syscall_64+0x50/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+This happens because we're allocating the scrub workqueues under the
+scrub and device list mutex, which brings in a whole host of other
+dependencies.
+
+Because the work queue allocation is done with GFP_KERNEL, it can
+trigger reclaim, which can lead to a transaction commit, which in turns
+needs the device_list_mutex, it can lead to a deadlock. A different
+problem for which this fix is a solution.
+
+Fix this by moving the actual allocation outside of the
+scrub lock, and then only take the lock once we're ready to actually
+assign them to the fs_info. We'll now have to cleanup the workqueues in
+a few more places, so I've added a helper to do the refcount dance to
+safely free the workqueues.
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/scrub.c | 122 +++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 70 insertions(+), 52 deletions(-)
+
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -3742,50 +3742,84 @@ static noinline_for_stack int scrub_supe
+ return 0;
+ }
+
++static void scrub_workers_put(struct btrfs_fs_info *fs_info)
++{
++ if (refcount_dec_and_mutex_lock(&fs_info->scrub_workers_refcnt,
++ &fs_info->scrub_lock)) {
++ struct btrfs_workqueue *scrub_workers = NULL;
++ struct btrfs_workqueue *scrub_wr_comp = NULL;
++ struct btrfs_workqueue *scrub_parity = NULL;
++
++ scrub_workers = fs_info->scrub_workers;
++ scrub_wr_comp = fs_info->scrub_wr_completion_workers;
++ scrub_parity = fs_info->scrub_parity_workers;
++
++ fs_info->scrub_workers = NULL;
++ fs_info->scrub_wr_completion_workers = NULL;
++ fs_info->scrub_parity_workers = NULL;
++ mutex_unlock(&fs_info->scrub_lock);
++
++ btrfs_destroy_workqueue(scrub_workers);
++ btrfs_destroy_workqueue(scrub_wr_comp);
++ btrfs_destroy_workqueue(scrub_parity);
++ }
++}
++
+ /*
+ * get a reference count on fs_info->scrub_workers. start worker if necessary
+ */
+ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
+ int is_dev_replace)
+ {
++ struct btrfs_workqueue *scrub_workers = NULL;
++ struct btrfs_workqueue *scrub_wr_comp = NULL;
++ struct btrfs_workqueue *scrub_parity = NULL;
+ unsigned int flags = WQ_FREEZABLE | WQ_UNBOUND;
+ int max_active = fs_info->thread_pool_size;
++ int ret = -ENOMEM;
+
+- lockdep_assert_held(&fs_info->scrub_lock);
++ if (refcount_inc_not_zero(&fs_info->scrub_workers_refcnt))
++ return 0;
+
+- if (refcount_read(&fs_info->scrub_workers_refcnt) == 0) {
+- ASSERT(fs_info->scrub_workers == NULL);
+- fs_info->scrub_workers = btrfs_alloc_workqueue(fs_info, "scrub",
+- flags, is_dev_replace ? 1 : max_active, 4);
+- if (!fs_info->scrub_workers)
+- goto fail_scrub_workers;
+-
+- ASSERT(fs_info->scrub_wr_completion_workers == NULL);
+- fs_info->scrub_wr_completion_workers =
+- btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
+- max_active, 2);
+- if (!fs_info->scrub_wr_completion_workers)
+- goto fail_scrub_wr_completion_workers;
++ scrub_workers = btrfs_alloc_workqueue(fs_info, "scrub", flags,
++ is_dev_replace ? 1 : max_active, 4);
++ if (!scrub_workers)
++ goto fail_scrub_workers;
+
+- ASSERT(fs_info->scrub_parity_workers == NULL);
+- fs_info->scrub_parity_workers =
+- btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
++ scrub_wr_comp = btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
+ max_active, 2);
+- if (!fs_info->scrub_parity_workers)
+- goto fail_scrub_parity_workers;
++ if (!scrub_wr_comp)
++ goto fail_scrub_wr_completion_workers;
+
++ scrub_parity = btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
++ max_active, 2);
++ if (!scrub_parity)
++ goto fail_scrub_parity_workers;
++
++ mutex_lock(&fs_info->scrub_lock);
++ if (refcount_read(&fs_info->scrub_workers_refcnt) == 0) {
++ ASSERT(fs_info->scrub_workers == NULL &&
++ fs_info->scrub_wr_completion_workers == NULL &&
++ fs_info->scrub_parity_workers == NULL);
++ fs_info->scrub_workers = scrub_workers;
++ fs_info->scrub_wr_completion_workers = scrub_wr_comp;
++ fs_info->scrub_parity_workers = scrub_parity;
+ refcount_set(&fs_info->scrub_workers_refcnt, 1);
+- } else {
+- refcount_inc(&fs_info->scrub_workers_refcnt);
++ mutex_unlock(&fs_info->scrub_lock);
++ return 0;
+ }
+- return 0;
++ /* Other thread raced in and created the workers for us */
++ refcount_inc(&fs_info->scrub_workers_refcnt);
++ mutex_unlock(&fs_info->scrub_lock);
+
++ ret = 0;
++ btrfs_destroy_workqueue(scrub_parity);
+ fail_scrub_parity_workers:
+- btrfs_destroy_workqueue(fs_info->scrub_wr_completion_workers);
++ btrfs_destroy_workqueue(scrub_wr_comp);
+ fail_scrub_wr_completion_workers:
+- btrfs_destroy_workqueue(fs_info->scrub_workers);
++ btrfs_destroy_workqueue(scrub_workers);
+ fail_scrub_workers:
+- return -ENOMEM;
++ return ret;
+ }
+
+ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+@@ -3796,9 +3830,6 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+ int ret;
+ struct btrfs_device *dev;
+ unsigned int nofs_flag;
+- struct btrfs_workqueue *scrub_workers = NULL;
+- struct btrfs_workqueue *scrub_wr_comp = NULL;
+- struct btrfs_workqueue *scrub_parity = NULL;
+
+ if (btrfs_fs_closing(fs_info))
+ return -EAGAIN;
+@@ -3845,13 +3876,17 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+ if (IS_ERR(sctx))
+ return PTR_ERR(sctx);
+
++ ret = scrub_workers_get(fs_info, is_dev_replace);
++ if (ret)
++ goto out_free_ctx;
++
+ mutex_lock(&fs_info->fs_devices->device_list_mutex);
+ dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL, true);
+ if (!dev || (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) &&
+ !is_dev_replace)) {
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+ ret = -ENODEV;
+- goto out_free_ctx;
++ goto out;
+ }
+
+ if (!is_dev_replace && !readonly &&
+@@ -3860,7 +3895,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+ btrfs_err_in_rcu(fs_info, "scrub: device %s is not writable",
+ rcu_str_deref(dev->name));
+ ret = -EROFS;
+- goto out_free_ctx;
++ goto out;
+ }
+
+ mutex_lock(&fs_info->scrub_lock);
+@@ -3869,7 +3904,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+ mutex_unlock(&fs_info->scrub_lock);
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+ ret = -EIO;
+- goto out_free_ctx;
++ goto out;
+ }
+
+ down_read(&fs_info->dev_replace.rwsem);
+@@ -3880,17 +3915,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+ mutex_unlock(&fs_info->scrub_lock);
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+ ret = -EINPROGRESS;
+- goto out_free_ctx;
++ goto out;
+ }
+ up_read(&fs_info->dev_replace.rwsem);
+
+- ret = scrub_workers_get(fs_info, is_dev_replace);
+- if (ret) {
+- mutex_unlock(&fs_info->scrub_lock);
+- mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+- goto out_free_ctx;
+- }
+-
+ sctx->readonly = readonly;
+ dev->scrub_ctx = sctx;
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+@@ -3943,24 +3971,14 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+
+ mutex_lock(&fs_info->scrub_lock);
+ dev->scrub_ctx = NULL;
+- if (refcount_dec_and_test(&fs_info->scrub_workers_refcnt)) {
+- scrub_workers = fs_info->scrub_workers;
+- scrub_wr_comp = fs_info->scrub_wr_completion_workers;
+- scrub_parity = fs_info->scrub_parity_workers;
+-
+- fs_info->scrub_workers = NULL;
+- fs_info->scrub_wr_completion_workers = NULL;
+- fs_info->scrub_parity_workers = NULL;
+- }
+ mutex_unlock(&fs_info->scrub_lock);
+
+- btrfs_destroy_workqueue(scrub_workers);
+- btrfs_destroy_workqueue(scrub_wr_comp);
+- btrfs_destroy_workqueue(scrub_parity);
++ scrub_workers_put(fs_info);
+ scrub_put_ctx(sctx);
+
+ return ret;
+-
++out:
++ scrub_workers_put(fs_info);
+ out_free_ctx:
+ scrub_free_ctx(sctx);
+
--- /dev/null
+From 9771a5cf937129307d9f58922d60484d58ababe7 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:26 -0400
+Subject: btrfs: drop path before adding new uuid tree entry
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 9771a5cf937129307d9f58922d60484d58ababe7 upstream.
+
+With the conversion of the tree locks to rwsem I got the following
+lockdep splat:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.8.0-rc7-00167-g0d7ba0c5b375-dirty #925 Not tainted
+ ------------------------------------------------------
+ btrfs-uuid/7955 is trying to acquire lock:
+ ffff88bfbafec0f8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x39/0x180
+
+ but task is already holding lock:
+ ffff88bfbafef2a8 (btrfs-uuid-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x39/0x180
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #1 (btrfs-uuid-00){++++}-{3:3}:
+ down_read_nested+0x3e/0x140
+ __btrfs_tree_read_lock+0x39/0x180
+ __btrfs_read_lock_root_node+0x3a/0x50
+ btrfs_search_slot+0x4bd/0x990
+ btrfs_uuid_tree_add+0x89/0x2d0
+ btrfs_uuid_scan_kthread+0x330/0x390
+ kthread+0x133/0x150
+ ret_from_fork+0x1f/0x30
+
+ -> #0 (btrfs-root-00){++++}-{3:3}:
+ __lock_acquire+0x1272/0x2310
+ lock_acquire+0x9e/0x360
+ down_read_nested+0x3e/0x140
+ __btrfs_tree_read_lock+0x39/0x180
+ __btrfs_read_lock_root_node+0x3a/0x50
+ btrfs_search_slot+0x4bd/0x990
+ btrfs_find_root+0x45/0x1b0
+ btrfs_read_tree_root+0x61/0x100
+ btrfs_get_root_ref.part.50+0x143/0x630
+ btrfs_uuid_tree_iterate+0x207/0x314
+ btrfs_uuid_rescan_kthread+0x12/0x50
+ kthread+0x133/0x150
+ ret_from_fork+0x1f/0x30
+
+ other info that might help us debug this:
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(btrfs-uuid-00);
+ lock(btrfs-root-00);
+ lock(btrfs-uuid-00);
+ lock(btrfs-root-00);
+
+ *** DEADLOCK ***
+
+ 1 lock held by btrfs-uuid/7955:
+ #0: ffff88bfbafef2a8 (btrfs-uuid-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x39/0x180
+
+ stack backtrace:
+ CPU: 73 PID: 7955 Comm: btrfs-uuid Kdump: loaded Not tainted 5.8.0-rc7-00167-g0d7ba0c5b375-dirty #925
+ Hardware name: Quanta Tioga Pass Single Side 01-0030993006/Tioga Pass Single Side, BIOS F08_3A18 12/20/2018
+ Call Trace:
+ dump_stack+0x78/0xa0
+ check_noncircular+0x165/0x180
+ __lock_acquire+0x1272/0x2310
+ lock_acquire+0x9e/0x360
+ ? __btrfs_tree_read_lock+0x39/0x180
+ ? btrfs_root_node+0x1c/0x1d0
+ down_read_nested+0x3e/0x140
+ ? __btrfs_tree_read_lock+0x39/0x180
+ __btrfs_tree_read_lock+0x39/0x180
+ __btrfs_read_lock_root_node+0x3a/0x50
+ btrfs_search_slot+0x4bd/0x990
+ btrfs_find_root+0x45/0x1b0
+ btrfs_read_tree_root+0x61/0x100
+ btrfs_get_root_ref.part.50+0x143/0x630
+ btrfs_uuid_tree_iterate+0x207/0x314
+ ? btree_readpage+0x20/0x20
+ btrfs_uuid_rescan_kthread+0x12/0x50
+ kthread+0x133/0x150
+ ? kthread_create_on_node+0x60/0x60
+ ret_from_fork+0x1f/0x30
+
+This problem exists because we have two different rescan threads,
+btrfs_uuid_scan_kthread which creates the uuid tree, and
+btrfs_uuid_tree_iterate that goes through and updates or deletes any out
+of date roots. The problem is they both do things in different order.
+btrfs_uuid_scan_kthread() reads the tree_root, and then inserts entries
+into the uuid_root. btrfs_uuid_tree_iterate() scans the uuid_root, but
+then does a btrfs_get_fs_root() which can read from the tree_root.
+
+It's actually easy enough to not be holding the path in
+btrfs_uuid_scan_kthread() when we add a uuid entry, as we already drop
+it further down and re-start the search when we loop. So simply move
+the path release before we add our entry to the uuid tree.
+
+This also fixes a problem where we're holding a path open after we do
+btrfs_end_transaction(), which has it's own problems.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -4568,6 +4568,7 @@ static int btrfs_uuid_scan_kthread(void
+ goto skip;
+ }
+ update_tree:
++ btrfs_release_path(path);
+ if (!btrfs_is_empty_uuid(root_item.uuid)) {
+ ret = btrfs_uuid_tree_add(trans, root_item.uuid,
+ BTRFS_UUID_KEY_SUBVOL,
+@@ -4592,6 +4593,7 @@ update_tree:
+ }
+
+ skip:
++ btrfs_release_path(path);
+ if (trans) {
+ ret = btrfs_end_transaction(trans);
+ trans = NULL;
+@@ -4599,7 +4601,6 @@ skip:
+ break;
+ }
+
+- btrfs_release_path(path);
+ if (key.offset < (u64)-1) {
+ key.offset++;
+ } else if (key.type < BTRFS_ROOT_ITEM_KEY) {
--- /dev/null
+From ad24466588ab7d7c879053c5afd919b0c555fec0 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:30 -0400
+Subject: btrfs: set the correct lockdep class for new nodes
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit ad24466588ab7d7c879053c5afd919b0c555fec0 upstream.
+
+When flipping over to the rw_semaphore I noticed I'd get a lockdep splat
+in replace_path(), which is weird because we're swapping the reloc root
+with the actual target root. Turns out this is because we're using the
+root->root_key.objectid as the root id for the newly allocated tree
+block when setting the lockdep class, however we need to be using the
+actual owner of this new block, which is saved in owner.
+
+The affected path is through btrfs_copy_root as all other callers of
+btrfs_alloc_tree_block (which calls init_new_buffer) have root_objectid
+== root->root_key.objectid .
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4446,7 +4446,7 @@ btrfs_init_new_buffer(struct btrfs_trans
+ return ERR_PTR(-EUCLEAN);
+ }
+
+- btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level);
++ btrfs_set_buffer_lockdep_class(owner, buf, level);
+ btrfs_tree_lock(buf);
+ btrfs_clean_tree_block(buf);
+ clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);
--- /dev/null
+From d3beaa253fd6fa40b8b18a216398e6e5376a9d21 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:31 -0400
+Subject: btrfs: set the lockdep class for log tree extent buffers
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit d3beaa253fd6fa40b8b18a216398e6e5376a9d21 upstream.
+
+These are special extent buffers that get rewound in order to lookup
+the state of the tree at a specific point in time. As such they do not
+go through the normal initialization paths that set their lockdep class,
+so handle them appropriately when they are created and before they are
+locked.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ctree.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1339,6 +1339,8 @@ tree_mod_log_rewind(struct btrfs_fs_info
+ btrfs_tree_read_unlock_blocking(eb);
+ free_extent_buffer(eb);
+
++ btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb_rewin),
++ eb_rewin, btrfs_header_level(eb_rewin));
+ btrfs_tree_read_lock(eb_rewin);
+ __tree_mod_log_rewind(fs_info, eb_rewin, time_seq, tm);
+ WARN_ON(btrfs_header_nritems(eb_rewin) >
+@@ -1412,7 +1414,6 @@ get_old_root(struct btrfs_root *root, u6
+
+ if (!eb)
+ return NULL;
+- btrfs_tree_read_lock(eb);
+ if (old_root) {
+ btrfs_set_header_bytenr(eb, eb->start);
+ btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV);
+@@ -1420,6 +1421,9 @@ get_old_root(struct btrfs_root *root, u6
+ btrfs_set_header_level(eb, old_root->level);
+ btrfs_set_header_generation(eb, old_generation);
+ }
++ btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb), eb,
++ btrfs_header_level(eb));
++ btrfs_tree_read_lock(eb);
+ if (tm)
+ __tree_mod_log_rewind(fs_info, eb, time_seq, tm);
+ else
--- /dev/null
+From f96d6960abbc52e26ad124e69e6815283d3e1674 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 25 Aug 2020 21:42:51 +0800
+Subject: btrfs: tree-checker: fix the error message for transid error
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit f96d6960abbc52e26ad124e69e6815283d3e1674 upstream.
+
+The error message for inode transid is the same as for inode generation,
+which makes us unable to detect the real problem.
+
+Reported-by: Tyler Richmond <t.d.richmond@gmail.com>
+Fixes: 496245cac57e ("btrfs: tree-checker: Verify inode item")
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Marcos Paulo de Souza <mpdesouza@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-checker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -772,7 +772,7 @@ static int check_inode_item(struct exten
+ /* Here we use super block generation + 1 to handle log tree */
+ if (btrfs_inode_generation(leaf, iitem) > super_gen + 1) {
+ inode_item_err(fs_info, leaf, slot,
+- "invalid inode generation: has %llu expect (0, %llu]",
++ "invalid inode transid: has %llu expect [0, %llu]",
+ btrfs_inode_generation(leaf, iitem),
+ super_gen + 1);
+ return -EUCLEAN;
--- /dev/null
+From 1ef6ea0efe8e68d0299dad44c39dc6ad9e5d1f39 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Sat, 5 Sep 2020 08:12:01 -0400
+Subject: ext2: don't update mtime on COW faults
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 1ef6ea0efe8e68d0299dad44c39dc6ad9e5d1f39 upstream.
+
+When running in a dax mode, if the user maps a page with MAP_PRIVATE and
+PROT_WRITE, the ext2 filesystem would incorrectly update ctime and mtime
+when the user hits a COW fault.
+
+This breaks building of the Linux kernel. How to reproduce:
+
+ 1. extract the Linux kernel tree on dax-mounted ext2 filesystem
+ 2. run make clean
+ 3. run make -j12
+ 4. run make -j12
+
+at step 4, make would incorrectly rebuild the whole kernel (although it
+was already built in step 3).
+
+The reason for the breakage is that almost all object files depend on
+objtool. When we run objtool, it takes COW page fault on its .data
+section, and these faults will incorrectly update the timestamp of the
+objtool binary. The updated timestamp causes make to rebuild the whole
+tree.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext2/file.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext2/file.c
++++ b/fs/ext2/file.c
+@@ -93,8 +93,10 @@ static vm_fault_t ext2_dax_fault(struct
+ struct inode *inode = file_inode(vmf->vma->vm_file);
+ struct ext2_inode_info *ei = EXT2_I(inode);
+ vm_fault_t ret;
++ bool write = (vmf->flags & FAULT_FLAG_WRITE) &&
++ (vmf->vma->vm_flags & VM_SHARED);
+
+- if (vmf->flags & FAULT_FLAG_WRITE) {
++ if (write) {
+ sb_start_pagefault(inode->i_sb);
+ file_update_time(vmf->vma->vm_file);
+ }
+@@ -103,7 +105,7 @@ static vm_fault_t ext2_dax_fault(struct
+ ret = dax_iomap_fault(vmf, PE_SIZE_PTE, NULL, NULL, &ext2_iomap_ops);
+
+ up_read(&ei->dax_sem);
+- if (vmf->flags & FAULT_FLAG_WRITE)
++ if (write)
+ sb_end_pagefault(inode->i_sb);
+ return ret;
+ }
--- /dev/null
+From 29aaebbca4abc4cceb38738483051abefafb6950 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Sat, 22 Aug 2020 17:02:09 +0100
+Subject: iommu/vt-d: Handle 36bit addressing for x86-32
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 29aaebbca4abc4cceb38738483051abefafb6950 upstream.
+
+Beware that the address size for x86-32 may exceed unsigned long.
+
+[ 0.368971] UBSAN: shift-out-of-bounds in drivers/iommu/intel/iommu.c:128:14
+[ 0.369055] shift exponent 36 is too large for 32-bit type 'long unsigned int'
+
+If we don't handle the wide addresses, the pages are mismapped and the
+device read/writes go astray, detected as DMAR faults and leading to
+device failure. The behaviour changed (from working to broken) in commit
+fa954e683178 ("iommu/vt-d: Delegate the dma domain to upper layer"), but
+the error looks older.
+
+Fixes: fa954e683178 ("iommu/vt-d: Delegate the dma domain to upper layer")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Acked-by: Lu Baolu <baolu.lu@linux.intel.com>
+Cc: James Sewart <jamessewart@arista.com>
+Cc: Lu Baolu <baolu.lu@linux.intel.com>
+Cc: Joerg Roedel <jroedel@suse.de>
+Cc: <stable@vger.kernel.org> # v5.3+
+Link: https://lore.kernel.org/r/20200822160209.28512-1-chris@chris-wilson.co.uk
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -123,29 +123,29 @@ static inline unsigned int level_to_offs
+ return (level - 1) * LEVEL_STRIDE;
+ }
+
+-static inline int pfn_level_offset(unsigned long pfn, int level)
++static inline int pfn_level_offset(u64 pfn, int level)
+ {
+ return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
+ }
+
+-static inline unsigned long level_mask(int level)
++static inline u64 level_mask(int level)
+ {
+- return -1UL << level_to_offset_bits(level);
++ return -1ULL << level_to_offset_bits(level);
+ }
+
+-static inline unsigned long level_size(int level)
++static inline u64 level_size(int level)
+ {
+- return 1UL << level_to_offset_bits(level);
++ return 1ULL << level_to_offset_bits(level);
+ }
+
+-static inline unsigned long align_to_level(unsigned long pfn, int level)
++static inline u64 align_to_level(u64 pfn, int level)
+ {
+ return (pfn + level_size(level) - 1) & level_mask(level);
+ }
+
+ static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
+ {
+- return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
++ return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
+ }
+
+ /* VT-d pages must always be _smaller_ than MM pages. Otherwise things
vfio-type1-support-faulting-pfnmap-vmas.patch
vfio-pci-fault-mmaps-to-enable-vma-tracking.patch
vfio-pci-invalidate-mmaps-and-block-mmio-access-on-d.patch
+iommu-vt-d-handle-36bit-addressing-for-x86-32.patch
+tracing-kprobes-x86-ptrace-fix-regs-argument-order-for-i386.patch
+ext2-don-t-update-mtime-on-cow-faults.patch
+xfs-don-t-update-mtime-on-cow-faults.patch
+arc-perf-don-t-bail-setup-if-pct-irq-missing-in-device-tree.patch
+btrfs-drop-path-before-adding-new-uuid-tree-entry.patch
+btrfs-allocate-scrub-workqueues-outside-of-locks.patch
+btrfs-set-the-correct-lockdep-class-for-new-nodes.patch
+btrfs-set-the-lockdep-class-for-log-tree-extent-buffers.patch
+btrfs-tree-checker-fix-the-error-message-for-transid-error.patch
--- /dev/null
+From 2356bb4b8221d7dc8c7beb810418122ed90254c9 Mon Sep 17 00:00:00 2001
+From: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
+Date: Fri, 28 Aug 2020 17:02:46 +0530
+Subject: tracing/kprobes, x86/ptrace: Fix regs argument order for i386
+
+From: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
+
+commit 2356bb4b8221d7dc8c7beb810418122ed90254c9 upstream.
+
+On i386, the order of parameters passed on regs is eax,edx,and ecx
+(as per regparm(3) calling conventions).
+
+Change the mapping in regs_get_kernel_argument(), so that arg1=ax
+arg2=dx, and arg3=cx.
+
+Running the selftests testcase kprobes_args_use.tc shows the result
+as passed.
+
+Fixes: 3c88ee194c28 ("x86: ptrace: Add function argument access API")
+Signed-off-by: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: <stable@vger.kernel.org>
+Link: https://lkml.kernel.org/r/20200828113242.GA1424@cosmos
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/ptrace.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/ptrace.h
++++ b/arch/x86/include/asm/ptrace.h
+@@ -309,8 +309,8 @@ static inline unsigned long regs_get_ker
+ static const unsigned int argument_offs[] = {
+ #ifdef __i386__
+ offsetof(struct pt_regs, ax),
+- offsetof(struct pt_regs, cx),
+ offsetof(struct pt_regs, dx),
++ offsetof(struct pt_regs, cx),
+ #define NR_REG_ARGUMENTS 3
+ #else
+ offsetof(struct pt_regs, di),
--- /dev/null
+From b17164e258e3888d376a7434415013175d637377 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Sat, 5 Sep 2020 08:13:02 -0400
+Subject: xfs: don't update mtime on COW faults
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit b17164e258e3888d376a7434415013175d637377 upstream.
+
+When running in a dax mode, if the user maps a page with MAP_PRIVATE and
+PROT_WRITE, the xfs filesystem would incorrectly update ctime and mtime
+when the user hits a COW fault.
+
+This breaks building of the Linux kernel. How to reproduce:
+
+ 1. extract the Linux kernel tree on dax-mounted xfs filesystem
+ 2. run make clean
+ 3. run make -j12
+ 4. run make -j12
+
+at step 4, make would incorrectly rebuild the whole kernel (although it
+was already built in step 3).
+
+The reason for the breakage is that almost all object files depend on
+objtool. When we run objtool, it takes COW page fault on its .data
+section, and these faults will incorrectly update the timestamp of the
+objtool binary. The updated timestamp causes make to rebuild the whole
+tree.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_file.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -1172,6 +1172,14 @@ __xfs_filemap_fault(
+ return ret;
+ }
+
++static inline bool
++xfs_is_write_fault(
++ struct vm_fault *vmf)
++{
++ return (vmf->flags & FAULT_FLAG_WRITE) &&
++ (vmf->vma->vm_flags & VM_SHARED);
++}
++
+ static vm_fault_t
+ xfs_filemap_fault(
+ struct vm_fault *vmf)
+@@ -1179,7 +1187,7 @@ xfs_filemap_fault(
+ /* DAX can shortcut the normal fault path on write faults! */
+ return __xfs_filemap_fault(vmf, PE_SIZE_PTE,
+ IS_DAX(file_inode(vmf->vma->vm_file)) &&
+- (vmf->flags & FAULT_FLAG_WRITE));
++ xfs_is_write_fault(vmf));
+ }
+
+ static vm_fault_t
+@@ -1192,7 +1200,7 @@ xfs_filemap_huge_fault(
+
+ /* DAX can shortcut the normal fault path on write faults! */
+ return __xfs_filemap_fault(vmf, pe_size,
+- (vmf->flags & FAULT_FLAG_WRITE));
++ xfs_is_write_fault(vmf));
+ }
+
+ static vm_fault_t