From: Sasha Levin Date: Fri, 23 Nov 2018 20:02:10 +0000 (-0500) Subject: patches for 4.9 X-Git-Tag: v3.18.127~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=872d217c708d34bc8011e142f4ca0bc7f4d19c3e;p=thirdparty%2Fkernel%2Fstable-queue.git patches for 4.9 Signed-off-by: Sasha Levin --- diff --git a/queue-4.9/acpi-watchdog-prefer-itco_wdt-always-when-wdat-table.patch b/queue-4.9/acpi-watchdog-prefer-itco_wdt-always-when-wdat-table.patch new file mode 100644 index 00000000000..ef867f5e307 --- /dev/null +++ b/queue-4.9/acpi-watchdog-prefer-itco_wdt-always-when-wdat-table.patch @@ -0,0 +1,130 @@ +From 1fc659f42cb77ebb64f20de05c6446877d894452 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Tue, 22 May 2018 14:16:50 +0300 +Subject: ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM + +[ Upstream commit 5a802a7a285c8877ca872e44eeb0f06afcb5212f ] + +After we added quirk for Lenovo Z50-70 it turns out there are at least +two more systems where WDAT table includes instructions accessing RTC +SRAM. Instead of quirking each system separately, look for such +instructions in the table and automatically prefer iTCO_wdt if found. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=199033 +Reported-by: Arnold Guy +Reported-by: Alois Nespor +Reported-by: Yury Pakin +Reported-by: Ihor Chyhin +Signed-off-by: Mika Westerberg +Acked-by: Guenter Roeck +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpi_watchdog.c | 72 ++++++++++++++++++++++-------------- + 1 file changed, 45 insertions(+), 27 deletions(-) + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index ca2724893541..396e358c2cee 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -12,35 +12,51 @@ + #define pr_fmt(fmt) "ACPI: watchdog: " fmt + + #include +-#include + #include + #include + + #include "internal.h" + +-static const struct dmi_system_id acpi_watchdog_skip[] = { +- { +- /* +- * On Lenovo Z50-70 there are two issues with the WDAT +- * table. First some of the instructions use RTC SRAM +- * to store persistent information. This does not work well +- * with Linux RTC driver. Second, more important thing is +- * that the instructions do not actually reset the system. +- * +- * On this particular system iTCO_wdt seems to work just +- * fine so we prefer that over WDAT for now. +- * +- * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. +- */ +- .ident = "Lenovo Z50-70", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "20354"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"), +- }, +- }, +- {} +-}; ++#ifdef CONFIG_RTC_MC146818_LIB ++#include ++ ++/* ++ * There are several systems where the WDAT table is accessing RTC SRAM to ++ * store persistent information. This does not work well with the Linux RTC ++ * driver so on those systems we skip WDAT driver and prefer iTCO_wdt ++ * instead. ++ * ++ * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. ++ */ ++static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) ++{ ++ const struct acpi_wdat_entry *entries; ++ int i; ++ ++ entries = (struct acpi_wdat_entry *)(wdat + 1); ++ for (i = 0; i < wdat->entries; i++) { ++ const struct acpi_generic_address *gas; ++ ++ gas = &entries[i].register_region; ++ if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { ++ switch (gas->address) { ++ case RTC_PORT(0): ++ case RTC_PORT(1): ++ case RTC_PORT(2): ++ case RTC_PORT(3): ++ return true; ++ } ++ } ++ } ++ ++ return false; ++} ++#else ++static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) ++{ ++ return false; ++} ++#endif + + static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) + { +@@ -50,9 +66,6 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) + if (acpi_disabled) + return NULL; + +- if (dmi_check_system(acpi_watchdog_skip)) +- return NULL; +- + status = acpi_get_table(ACPI_SIG_WDAT, 0, + (struct acpi_table_header **)&wdat); + if (ACPI_FAILURE(status)) { +@@ -60,6 +73,11 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) + return NULL; + } + ++ if (acpi_watchdog_uses_rtc(wdat)) { ++ pr_info("Skipping WDAT on this system because it uses RTC SRAM\n"); ++ return NULL; ++ } ++ + return wdat; + } + +-- +2.17.1 + diff --git a/queue-4.9/acpi-watchdog-prefer-itco_wdt-on-lenovo-z50-70.patch b/queue-4.9/acpi-watchdog-prefer-itco_wdt-on-lenovo-z50-70.patch new file mode 100644 index 00000000000..00569452b76 --- /dev/null +++ b/queue-4.9/acpi-watchdog-prefer-itco_wdt-on-lenovo-z50-70.patch @@ -0,0 +1,120 @@ +From fa963e96497983a53d58435039de883605fb70fe Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Mon, 23 Apr 2018 14:16:03 +0300 +Subject: ACPI / watchdog: Prefer iTCO_wdt on Lenovo Z50-70 + +[ Upstream commit a0a37862a4e1844793d39aca9ccb8fecbdcb8659 ] + +WDAT table on Lenovo Z50-70 is using RTC SRAM (ports 0x70 and 0x71) to +store state of the timer. This conflicts with Linux RTC driver +(rtc-cmos.c) who fails to reserve those ports for itself preventing RTC +from functioning. In addition the WDAT table seems not to be fully +functional because it does not reset the system when the watchdog times +out. + +On this system iTCO_wdt works just fine so we simply prefer to use it +instead of WDAT. This makes RTC working again and also results working +watchdog via iTCO_wdt. + +Reported-by: Peter Milley +Link: https://bugzilla.kernel.org/show_bug.cgi?id=199033 +Signed-off-by: Mika Westerberg +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpi_watchdog.c | 59 ++++++++++++++++++++++++++++++------ + 1 file changed, 49 insertions(+), 10 deletions(-) + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index ce8fc680785b..ca2724893541 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -12,23 +12,64 @@ + #define pr_fmt(fmt) "ACPI: watchdog: " fmt + + #include ++#include + #include + #include + + #include "internal.h" + ++static const struct dmi_system_id acpi_watchdog_skip[] = { ++ { ++ /* ++ * On Lenovo Z50-70 there are two issues with the WDAT ++ * table. First some of the instructions use RTC SRAM ++ * to store persistent information. This does not work well ++ * with Linux RTC driver. Second, more important thing is ++ * that the instructions do not actually reset the system. ++ * ++ * On this particular system iTCO_wdt seems to work just ++ * fine so we prefer that over WDAT for now. ++ * ++ * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. ++ */ ++ .ident = "Lenovo Z50-70", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "20354"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"), ++ }, ++ }, ++ {} ++}; ++ ++static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) ++{ ++ const struct acpi_table_wdat *wdat = NULL; ++ acpi_status status; ++ ++ if (acpi_disabled) ++ return NULL; ++ ++ if (dmi_check_system(acpi_watchdog_skip)) ++ return NULL; ++ ++ status = acpi_get_table(ACPI_SIG_WDAT, 0, ++ (struct acpi_table_header **)&wdat); ++ if (ACPI_FAILURE(status)) { ++ /* It is fine if there is no WDAT */ ++ return NULL; ++ } ++ ++ return wdat; ++} ++ + /** + * Returns true if this system should prefer ACPI based watchdog instead of + * the native one (which are typically the same hardware). + */ + bool acpi_has_watchdog(void) + { +- struct acpi_table_header hdr; +- +- if (acpi_disabled) +- return false; +- +- return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr)); ++ return !!acpi_watchdog_get_wdat(); + } + EXPORT_SYMBOL_GPL(acpi_has_watchdog); + +@@ -41,12 +82,10 @@ void __init acpi_watchdog_init(void) + struct platform_device *pdev; + struct resource *resources; + size_t nresources = 0; +- acpi_status status; + int i; + +- status = acpi_get_table(ACPI_SIG_WDAT, 0, +- (struct acpi_table_header **)&wdat); +- if (ACPI_FAILURE(status)) { ++ wdat = acpi_watchdog_get_wdat(); ++ if (!wdat) { + /* It is fine if there is no WDAT */ + return; + } +-- +2.17.1 + diff --git a/queue-4.9/btrfs-enhance-btrfs_trim_fs-function-to-handle-error.patch b/queue-4.9/btrfs-enhance-btrfs_trim_fs-function-to-handle-error.patch new file mode 100644 index 00000000000..8eff92c4223 --- /dev/null +++ b/queue-4.9/btrfs-enhance-btrfs_trim_fs-function-to-handle-error.patch @@ -0,0 +1,154 @@ +From e8418c468337b518374c976e640fc21e50ea5880 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 20 Nov 2018 10:26:36 +0800 +Subject: btrfs: Enhance btrfs_trim_fs function to handle error better + +Commit 93bba24d4b5ad1e5cd8b43f64e66ff9d6355dd20 upstream. + +Function btrfs_trim_fs() doesn't handle errors in a consistent way. If +error happens when trimming existing block groups, it will skip the +remaining blocks and continue to trim unallocated space for each device. + +The return value will only reflect the final error from device trimming. + +This patch will fix such behavior by: + +1) Recording the last error from block group or device trimming + The return value will also reflect the last error during trimming. + Make developer more aware of the problem. + +2) Continuing trimming if possible + If we failed to trim one block group or device, we could still try + the next block group or device. + +3) Report number of failures during block group and device trimming + It would be less noisy, but still gives user a brief summary of + what's going wrong. + +Such behavior can avoid confusion for cases like failure to trim the +first block group and then only unallocated space is trimmed. + +Reported-by: Chris Murphy +CC: stable@vger.kernel.org # 4.9 +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +[ add bg_ret and dev_ret to the messages ] +Signed-off-by: David Sterba +[ change parameter from @fs_info to @fs_info->root for older kernel ] +Signed-off-by: Sasha Levin +--- + fs/btrfs/extent-tree.c | 53 +++++++++++++++++++++++++++++++----------- + 1 file changed, 40 insertions(+), 13 deletions(-) + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 163b61a92b59..42c4b246f749 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -11140,6 +11140,15 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, + return ret; + } + ++/* ++ * Trim the whole filesystem by: ++ * 1) trimming the free space in each block group ++ * 2) trimming the unallocated space on each device ++ * ++ * This will also continue trimming even if a block group or device encounters ++ * an error. The return value will be the last error, or 0 if nothing bad ++ * happens. ++ */ + int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + { + struct btrfs_fs_info *fs_info = root->fs_info; +@@ -11151,6 +11160,10 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + u64 end; + u64 trimmed = 0; + u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); ++ u64 bg_failed = 0; ++ u64 dev_failed = 0; ++ int bg_ret = 0; ++ int dev_ret = 0; + int ret = 0; + + /* +@@ -11161,7 +11174,7 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + else + cache = btrfs_lookup_block_group(fs_info, range->start); + +- while (cache) { ++ for (; cache; cache = next_block_group(fs_info->tree_root, cache)) { + if (cache->key.objectid >= (range->start + range->len)) { + btrfs_put_block_group(cache); + break; +@@ -11175,13 +11188,15 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + if (!block_group_cache_done(cache)) { + ret = cache_block_group(cache, 0); + if (ret) { +- btrfs_put_block_group(cache); +- break; ++ bg_failed++; ++ bg_ret = ret; ++ continue; + } + ret = wait_block_group_cache_done(cache); + if (ret) { +- btrfs_put_block_group(cache); +- break; ++ bg_failed++; ++ bg_ret = ret; ++ continue; + } + } + ret = btrfs_trim_block_group(cache, +@@ -11192,28 +11207,40 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + + trimmed += group_trimmed; + if (ret) { +- btrfs_put_block_group(cache); +- break; ++ bg_failed++; ++ bg_ret = ret; ++ continue; + } + } +- +- cache = next_block_group(fs_info->tree_root, cache); + } + +- mutex_lock(&root->fs_info->fs_devices->device_list_mutex); +- devices = &root->fs_info->fs_devices->devices; ++ if (bg_failed) ++ btrfs_warn(fs_info, ++ "failed to trim %llu block group(s), last error %d", ++ bg_failed, bg_ret); ++ mutex_lock(&fs_info->fs_devices->device_list_mutex); ++ devices = &fs_info->fs_devices->devices; + list_for_each_entry(device, devices, dev_list) { + ret = btrfs_trim_free_extents(device, range->minlen, + &group_trimmed); +- if (ret) ++ if (ret) { ++ dev_failed++; ++ dev_ret = ret; + break; ++ } + + trimmed += group_trimmed; + } + mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); + ++ if (dev_failed) ++ btrfs_warn(fs_info, ++ "failed to trim %llu device(s), last error %d", ++ dev_failed, dev_ret); + range->len = trimmed; +- return ret; ++ if (bg_ret) ++ return bg_ret; ++ return dev_ret; + } + + /* +-- +2.17.1 + diff --git a/queue-4.9/btrfs-ensure-btrfs_trim_fs-can-trim-the-whole-filesy.patch b/queue-4.9/btrfs-ensure-btrfs_trim_fs-can-trim-the-whole-filesy.patch new file mode 100644 index 00000000000..1f618a5b1fd --- /dev/null +++ b/queue-4.9/btrfs-ensure-btrfs_trim_fs-can-trim-the-whole-filesy.patch @@ -0,0 +1,105 @@ +From b766d1d6e22f45de3b755200fc9c4c9733c35266 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 20 Nov 2018 10:26:37 +0800 +Subject: btrfs: Ensure btrfs_trim_fs can trim the whole filesystem + +Commit 6ba9fc8e628becf0e3ec94083450d089b0dec5f5 upstream. + +[BUG] +fstrim on some btrfs only trims the unallocated space, not trimming any +space in existing block groups. + +[CAUSE] +Before fstrim_range passed to btrfs_trim_fs(), it gets truncated to +range [0, super->total_bytes). So later btrfs_trim_fs() will only be +able to trim block groups in range [0, super->total_bytes). + +While for btrfs, any bytenr aligned to sectorsize is valid, since btrfs +uses its logical address space, there is nothing limiting the location +where we put block groups. + +For filesystem with frequent balance, it's quite easy to relocate all +block groups and bytenr of block groups will start beyond +super->total_bytes. + +In that case, btrfs will not trim existing block groups. + +[FIX] +Just remove the truncation in btrfs_ioctl_fitrim(), so btrfs_trim_fs() +can get the unmodified range, which is normally set to [0, U64_MAX]. + +Reported-by: Chris Murphy +Fixes: f4c697e6406d ("btrfs: return EINVAL if start > total_bytes in fitrim ioctl") +CC: # v4.9 +Signed-off-by: Qu Wenruo +Reviewed-by: Nikolay Borisov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +[ change parameter from @fs_info to @fs_info->root for older kernel ] +Signed-off-by: Sasha Levin +--- + fs/btrfs/extent-tree.c | 10 +--------- + fs/btrfs/ioctl.c | 11 +++++++---- + 2 files changed, 8 insertions(+), 13 deletions(-) + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 42c4b246f749..a775307f3b6b 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -11159,21 +11159,13 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + u64 start; + u64 end; + u64 trimmed = 0; +- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); + u64 bg_failed = 0; + u64 dev_failed = 0; + int bg_ret = 0; + int dev_ret = 0; + int ret = 0; + +- /* +- * try to trim all FS space, our block group may start from non-zero. +- */ +- if (range->len == total_bytes) +- cache = btrfs_lookup_first_block_group(fs_info, range->start); +- else +- cache = btrfs_lookup_block_group(fs_info, range->start); +- ++ cache = btrfs_lookup_first_block_group(fs_info, range->start); + for (; cache; cache = next_block_group(fs_info->tree_root, cache)) { + if (cache->key.objectid >= (range->start + range->len)) { + btrfs_put_block_group(cache); +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 96ad2778405b..242584a0d3b5 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -380,7 +380,6 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) + struct fstrim_range range; + u64 minlen = ULLONG_MAX; + u64 num_devices = 0; +- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); + int ret; + + if (!capable(CAP_SYS_ADMIN)) +@@ -404,11 +403,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) + return -EOPNOTSUPP; + if (copy_from_user(&range, arg, sizeof(range))) + return -EFAULT; +- if (range.start > total_bytes || +- range.len < fs_info->sb->s_blocksize) ++ ++ /* ++ * NOTE: Don't truncate the range using super->total_bytes. Bytenr of ++ * block group is in the logical address space, which can be any ++ * sectorsize aligned bytenr in the range [0, U64_MAX]. ++ */ ++ if (range.len < fs_info->sb->s_blocksize) + return -EINVAL; + +- range.len = min(range.len, total_bytes - range.start); + range.minlen = max(range.minlen, minlen); + ret = btrfs_trim_fs(fs_info->tree_root, &range); + if (ret < 0) +-- +2.17.1 + diff --git a/queue-4.9/btrfs-fix-pinned-underflow-after-transaction-aborted.patch b/queue-4.9/btrfs-fix-pinned-underflow-after-transaction-aborted.patch new file mode 100644 index 00000000000..0291539bcad --- /dev/null +++ b/queue-4.9/btrfs-fix-pinned-underflow-after-transaction-aborted.patch @@ -0,0 +1,122 @@ +From c3f95ca8a3e6d5167b03ec0a3cc300a6bbd8d054 Mon Sep 17 00:00:00 2001 +From: Lu Fengqi +Date: Tue, 20 Nov 2018 11:17:32 +0800 +Subject: btrfs: fix pinned underflow after transaction aborted + +commit fcd5e74288f7d36991b1f0fb96b8c57079645e38 upstream. + +When running generic/475, we may get the following warning in dmesg: + +[ 6902.102154] WARNING: CPU: 3 PID: 18013 at fs/btrfs/extent-tree.c:9776 btrfs_free_block_groups+0x2af/0x3b0 [btrfs] +[ 6902.109160] CPU: 3 PID: 18013 Comm: umount Tainted: G W O 4.19.0-rc8+ #8 +[ 6902.110971] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 +[ 6902.112857] RIP: 0010:btrfs_free_block_groups+0x2af/0x3b0 [btrfs] +[ 6902.118921] RSP: 0018:ffffc9000459bdb0 EFLAGS: 00010286 +[ 6902.120315] RAX: ffff880175050bb0 RBX: ffff8801124a8000 RCX: 0000000000170007 +[ 6902.121969] RDX: 0000000000000002 RSI: 0000000000170007 RDI: ffffffff8125fb74 +[ 6902.123716] RBP: ffff880175055d10 R08: 0000000000000000 R09: 0000000000000000 +[ 6902.125417] R10: 0000000000000000 R11: 0000000000000000 R12: ffff880175055d88 +[ 6902.127129] R13: ffff880175050bb0 R14: 0000000000000000 R15: dead000000000100 +[ 6902.129060] FS: 00007f4507223780(0000) GS:ffff88017ba00000(0000) knlGS:0000000000000000 +[ 6902.130996] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 6902.132558] CR2: 00005623599cac78 CR3: 000000014b700001 CR4: 00000000003606e0 +[ 6902.134270] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 6902.135981] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 6902.137836] Call Trace: +[ 6902.138939] close_ctree+0x171/0x330 [btrfs] +[ 6902.140181] ? kthread_stop+0x146/0x1f0 +[ 6902.141277] generic_shutdown_super+0x6c/0x100 +[ 6902.142517] kill_anon_super+0x14/0x30 +[ 6902.143554] btrfs_kill_super+0x13/0x100 [btrfs] +[ 6902.144790] deactivate_locked_super+0x2f/0x70 +[ 6902.146014] cleanup_mnt+0x3b/0x70 +[ 6902.147020] task_work_run+0x9e/0xd0 +[ 6902.148036] do_syscall_64+0x470/0x600 +[ 6902.149142] ? trace_hardirqs_off_thunk+0x1a/0x1c +[ 6902.150375] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 6902.151640] RIP: 0033:0x7f45077a6a7b +[ 6902.157324] RSP: 002b:00007ffd589f3e68 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6 +[ 6902.159187] RAX: 0000000000000000 RBX: 000055e8eec732b0 RCX: 00007f45077a6a7b +[ 6902.160834] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 000055e8eec73490 +[ 6902.162526] RBP: 0000000000000000 R08: 000055e8eec734b0 R09: 00007ffd589f26c0 +[ 6902.164141] R10: 0000000000000000 R11: 0000000000000246 R12: 000055e8eec73490 +[ 6902.165815] R13: 00007f4507ac61a4 R14: 0000000000000000 R15: 00007ffd589f40d8 +[ 6902.167553] irq event stamp: 0 +[ 6902.168998] hardirqs last enabled at (0): [<0000000000000000>] (null) +[ 6902.170731] hardirqs last disabled at (0): [] copy_process.part.55+0x3b0/0x1f00 +[ 6902.172773] softirqs last enabled at (0): [] copy_process.part.55+0x3b0/0x1f00 +[ 6902.174671] softirqs last disabled at (0): [<0000000000000000>] (null) +[ 6902.176407] ---[ end trace 463138c2986b275c ]--- +[ 6902.177636] BTRFS info (device dm-3): space_info 4 has 273465344 free, is not full +[ 6902.179453] BTRFS info (device dm-3): space_info total=276824064, used=4685824, pinned=18446744073708158976, reserved=0, may_use=0, readonly=65536 + +In the above line there's "pinned=18446744073708158976" which is an +unsigned u64 value of -1392640, an obvious underflow. + +When transaction_kthread is running cleanup_transaction(), another +fsstress is running btrfs_commit_transaction(). The +btrfs_finish_extent_commit() may get the same range as +btrfs_destroy_pinned_extent() got, which causes the pinned underflow. + +Fixes: d4b450cd4b33 ("Btrfs: fix race between transaction commit and empty block group removal") +CC: stable@vger.kernel.org # 4.4+ +Reviewed-by: Josef Bacik +Signed-off-by: Lu Fengqi +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 18d05323ca53..57d375c68e46 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4491,6 +4491,7 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root, + static int btrfs_destroy_pinned_extent(struct btrfs_root *root, + struct extent_io_tree *pinned_extents) + { ++ struct btrfs_fs_info *fs_info = root->fs_info; + struct extent_io_tree *unpin; + u64 start; + u64 end; +@@ -4500,21 +4501,31 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, + unpin = pinned_extents; + again: + while (1) { ++ /* ++ * The btrfs_finish_extent_commit() may get the same range as ++ * ours between find_first_extent_bit and clear_extent_dirty. ++ * Hence, hold the unused_bg_unpin_mutex to avoid double unpin ++ * the same extent range. ++ */ ++ mutex_lock(&fs_info->unused_bg_unpin_mutex); + ret = find_first_extent_bit(unpin, 0, &start, &end, + EXTENT_DIRTY, NULL); +- if (ret) ++ if (ret) { ++ mutex_unlock(&fs_info->unused_bg_unpin_mutex); + break; ++ } + + clear_extent_dirty(unpin, start, end); + btrfs_error_unpin_extent_range(root, start, end); ++ mutex_unlock(&fs_info->unused_bg_unpin_mutex); + cond_resched(); + } + + if (loop) { +- if (unpin == &root->fs_info->freed_extents[0]) +- unpin = &root->fs_info->freed_extents[1]; ++ if (unpin == &fs_info->freed_extents[0]) ++ unpin = &fs_info->freed_extents[1]; + else +- unpin = &root->fs_info->freed_extents[0]; ++ unpin = &fs_info->freed_extents[0]; + loop = false; + goto again; + } +-- +2.17.1 + diff --git a/queue-4.9/gfs2-put-bitmap-buffers-in-put_super.patch b/queue-4.9/gfs2-put-bitmap-buffers-in-put_super.patch new file mode 100644 index 00000000000..33bf8783be3 --- /dev/null +++ b/queue-4.9/gfs2-put-bitmap-buffers-in-put_super.patch @@ -0,0 +1,54 @@ +From 5205178b8f4cf48b8951532f132698fd65d00566 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 19 Nov 2018 17:22:32 +0100 +Subject: gfs2: Put bitmap buffers in put_super + +commit 10283ea525d30f2e99828978fd04d8427876a7ad upstream. + +gfs2_put_super calls gfs2_clear_rgrpd to destroy the gfs2_rgrpd objects +attached to the resource group glocks. That function should release the +buffers attached to the gfs2_bitmap objects (bi_bh), but the call to +gfs2_rgrp_brelse for doing that is missing. + +When gfs2_releasepage later runs across these buffers which are still +referenced, it refuses to free them. This causes the pages the buffers +are attached to to remain referenced as well. With enough mount/unmount +cycles, the system will eventually run out of memory. + +Fix this by adding the missing call to gfs2_rgrp_brelse in +gfs2_clear_rgrpd. + +(Also fix a gfs2_rgrp_relse -> gfs2_rgrp_brelse typo in a comment.) + +Fixes: 39b0f1e92908 ("GFS2: Don't brelse rgrp buffer_heads every allocation") +Cc: stable@vger.kernel.org # v4.9 +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/rgrp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c +index 832824994aae..073126707270 100644 +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -715,6 +715,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) + spin_lock(&gl->gl_lockref.lock); + gl->gl_object = NULL; + spin_unlock(&gl->gl_lockref.lock); ++ gfs2_rgrp_brelse(rgd); + gfs2_glock_add_to_lru(gl); + gfs2_glock_put(gl); + } +@@ -1125,7 +1126,7 @@ static u32 count_unlinked(struct gfs2_rgrpd *rgd) + * @rgd: the struct gfs2_rgrpd describing the RG to read in + * + * Read in all of a Resource Group's header and bitmap blocks. +- * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. ++ * Caller must eventually call gfs2_rgrp_brelse() to free the bitmaps. + * + * Returns: errno + */ +-- +2.17.1 + diff --git a/queue-4.9/revert-media-videobuf2-core-don-t-call-memop-finish-.patch b/queue-4.9/revert-media-videobuf2-core-don-t-call-memop-finish-.patch new file mode 100644 index 00000000000..c8f87d203ca --- /dev/null +++ b/queue-4.9/revert-media-videobuf2-core-don-t-call-memop-finish-.patch @@ -0,0 +1,54 @@ +From 545d414959bacfed182c7c8749f98d94604472a6 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Thu, 22 Nov 2018 12:43:56 +0100 +Subject: Revert "media: videobuf2-core: don't call memop 'finish' when + queueing" + +This reverts commit 9ac47200b51cb09d2f15dbefa67e0412741d98aa. + +This commit fixes a bug in upstream commit a136f59c0a1f ("vb2: Move +buffer cache synchronisation to prepare from queue") which isn't +present in 4.9. + +So as a result you get an UNBALANCED message in the kernel log if +this patch is applied: + +vb2: counters for queue ffffffc0f3687478, buffer 3: UNBALANCED! +vb2: buf_init: 1 buf_cleanup: 1 buf_prepare: 805 buf_finish: 805 +vb2: buf_queue: 806 buf_done: 806 +vb2: alloc: 0 put: 0 prepare: 806 finish: 805 mmap: 0 +vb2: get_userptr: 0 put_userptr: 0 +vb2: attach_dmabuf: 1 detach_dmabuf: 1 map_dmabuf: 805 unmap_dmabuf: 805 +vb2: get_dmabuf: 0 num_users: 1609 vaddr: 0 cookie: 805 + +Reverting this patch solves this regression. + +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/v4l2-core/videobuf2-core.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c +index f7ca1fab4808..4df4a1f402be 100644 +--- a/drivers/media/v4l2-core/videobuf2-core.c ++++ b/drivers/media/v4l2-core/videobuf2-core.c +@@ -914,12 +914,9 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) + dprintk(4, "done processing on buffer %d, state: %d\n", + vb->index, state); + +- if (state != VB2_BUF_STATE_QUEUED && +- state != VB2_BUF_STATE_REQUEUEING) { +- /* sync buffers */ +- for (plane = 0; plane < vb->num_planes; ++plane) +- call_void_memop(vb, finish, vb->planes[plane].mem_priv); +- } ++ /* sync buffers */ ++ for (plane = 0; plane < vb->num_planes; ++plane) ++ call_void_memop(vb, finish, vb->planes[plane].mem_priv); + + spin_lock_irqsave(&q->done_lock, flags); + if (state == VB2_BUF_STATE_QUEUED || +-- +2.17.1 + diff --git a/queue-4.9/series b/queue-4.9/series index 8611f38b7fb..b494767749c 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -22,3 +22,12 @@ lib-raid6-fix-arm64-test-build.patch i2c-omap-enable-for-arch_k3.patch qed-fix-memory-entry-leak-in-qed_init_sp_request.patch qed-fix-blocking-unlimited-spq-entries-leak.patch +zram-close-udev-startup-race-condition-as-default-gr.patch +sunrpc-drop-pointless-static-qualifier-in-xdr_get_ne.patch +gfs2-put-bitmap-buffers-in-put_super.patch +acpi-watchdog-prefer-itco_wdt-on-lenovo-z50-70.patch +acpi-watchdog-prefer-itco_wdt-always-when-wdat-table.patch +btrfs-enhance-btrfs_trim_fs-function-to-handle-error.patch +btrfs-ensure-btrfs_trim_fs-can-trim-the-whole-filesy.patch +btrfs-fix-pinned-underflow-after-transaction-aborted.patch +revert-media-videobuf2-core-don-t-call-memop-finish-.patch diff --git a/queue-4.9/sunrpc-drop-pointless-static-qualifier-in-xdr_get_ne.patch b/queue-4.9/sunrpc-drop-pointless-static-qualifier-in-xdr_get_ne.patch new file mode 100644 index 00000000000..8503b1fb50e --- /dev/null +++ b/queue-4.9/sunrpc-drop-pointless-static-qualifier-in-xdr_get_ne.patch @@ -0,0 +1,35 @@ +From eda4f59dfb1f915b6051e0b6aed2132e36631094 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Thu, 8 Nov 2018 02:04:57 +0000 +Subject: SUNRPC: drop pointless static qualifier in + xdr_get_next_encode_buffer() + +[ Upstream commit 025911a5f4e36955498ed50806ad1b02f0f76288 ] + +There is no need to have the '__be32 *p' variable static since new value +always be assigned before use it. + +Signed-off-by: YueHaibing +Cc: stable@vger.kernel.org +Signed-off-by: J. Bruce Fields +Signed-off-by: Sasha Levin +--- + net/sunrpc/xdr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c +index 1b38fc486351..69846c6574ef 100644 +--- a/net/sunrpc/xdr.c ++++ b/net/sunrpc/xdr.c +@@ -512,7 +512,7 @@ EXPORT_SYMBOL_GPL(xdr_commit_encode); + static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, + size_t nbytes) + { +- static __be32 *p; ++ __be32 *p; + int space_left; + int frag1bytes, frag2bytes; + +-- +2.17.1 + diff --git a/queue-4.9/zram-close-udev-startup-race-condition-as-default-gr.patch b/queue-4.9/zram-close-udev-startup-race-condition-as-default-gr.patch new file mode 100644 index 00000000000..67edb80fd25 --- /dev/null +++ b/queue-4.9/zram-close-udev-startup-race-condition-as-default-gr.patch @@ -0,0 +1,96 @@ +From c9ab864c21d58c2b944581c6d667288b4d0bcde7 Mon Sep 17 00:00:00 2001 +From: Minchan Kim +Date: Fri, 23 Nov 2018 15:28:02 +0900 +Subject: zram: close udev startup race condition as default groups + +commit fef912bf860e upstream. +commit 98af4d4df889 upstream. + +I got a report from Howard Chen that he saw zram and sysfs race(ie, +zram block device file is created but sysfs for it isn't yet) +when he tried to create new zram devices via hotadd knob. + +v4.20 kernel fixes it by [1, 2] but it's too large size to merge +into -stable so this patch fixes the problem by registering defualt +group by Greg KH's approach[3]. + +This patch should be applied to every stable tree [3.16+] currently +existing from kernel.org because the problem was introduced at 2.6.37 +by [4]. + +[1] fef912bf860e, block: genhd: add 'groups' argument to device_add_disk +[2] 98af4d4df889, zram: register default groups with device_add_disk() +[3] http://kroah.com/log/blog/2013/06/26/how-to-create-a-sysfs-file-correctly/ +[4] 33863c21e69e9, Staging: zram: Replace ioctls with sysfs interface + +Cc: Sergey Senozhatsky +Cc: Hannes Reinecke +Tested-by: Howard Chen +Signed-off-by: Minchan Kim +Signed-off-by: Sasha Levin +--- + drivers/block/zram/zram_drv.c | 26 ++++++-------------------- + 1 file changed, 6 insertions(+), 20 deletions(-) + +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index b7c0b69a02f5..d64a53d3270a 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -1223,6 +1223,11 @@ static struct attribute_group zram_disk_attr_group = { + .attrs = zram_disk_attrs, + }; + ++static const struct attribute_group *zram_disk_attr_groups[] = { ++ &zram_disk_attr_group, ++ NULL, ++}; ++ + /* + * Allocate and initialize new zram device. the function returns + * '>= 0' device_id upon success, and negative value otherwise. +@@ -1303,24 +1308,15 @@ static int zram_add(void) + zram->disk->queue->limits.discard_zeroes_data = 0; + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zram->disk->queue); + ++ disk_to_dev(zram->disk)->groups = zram_disk_attr_groups; + add_disk(zram->disk); + +- ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj, +- &zram_disk_attr_group); +- if (ret < 0) { +- pr_err("Error creating sysfs group for device %d\n", +- device_id); +- goto out_free_disk; +- } + strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); + zram->meta = NULL; + + pr_info("Added device: %s\n", zram->disk->disk_name); + return device_id; + +-out_free_disk: +- del_gendisk(zram->disk); +- put_disk(zram->disk); + out_free_queue: + blk_cleanup_queue(queue); + out_free_idr: +@@ -1348,16 +1344,6 @@ static int zram_remove(struct zram *zram) + zram->claim = true; + mutex_unlock(&bdev->bd_mutex); + +- /* +- * Remove sysfs first, so no one will perform a disksize +- * store while we destroy the devices. This also helps during +- * hot_remove -- zram_reset_device() is the last holder of +- * ->init_lock, no later/concurrent disksize_store() or any +- * other sysfs handlers are possible. +- */ +- sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, +- &zram_disk_attr_group); +- + /* Make sure all the pending I/O are finished */ + fsync_bdev(bdev); + zram_reset_device(zram); +-- +2.17.1 +