From 2887e4bfb1ccfb68d6c96f4df164ffd225120e89 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Feb 2021 16:16:14 +0100 Subject: [PATCH] 5.4-stable patches added patches: acpi-thermal-do-not-call-acpi_thermal_check-directly.patch arm64-do-not-pass-tagged-addresses-to-__is_lm_address.patch arm64-fix-kernel-address-detection-of-__is_lm_address.patch tcp-make-tcp_user_timeout-accurate-for-zero-window-probes.patch --- ...not-call-acpi_thermal_check-directly.patch | 176 ++++++++++++++++++ ...-tagged-addresses-to-__is_lm_address.patch | 53 ++++++ ...address-detection-of-__is_lm_address.patch | 49 +++++ queue-5.4/series | 4 + ...eout-accurate-for-zero-window-probes.patch | 92 +++++++++ 5 files changed, 374 insertions(+) create mode 100644 queue-5.4/acpi-thermal-do-not-call-acpi_thermal_check-directly.patch create mode 100644 queue-5.4/arm64-do-not-pass-tagged-addresses-to-__is_lm_address.patch create mode 100644 queue-5.4/arm64-fix-kernel-address-detection-of-__is_lm_address.patch create mode 100644 queue-5.4/tcp-make-tcp_user_timeout-accurate-for-zero-window-probes.patch diff --git a/queue-5.4/acpi-thermal-do-not-call-acpi_thermal_check-directly.patch b/queue-5.4/acpi-thermal-do-not-call-acpi_thermal_check-directly.patch new file mode 100644 index 00000000000..0f0b4984d74 --- /dev/null +++ b/queue-5.4/acpi-thermal-do-not-call-acpi_thermal_check-directly.patch @@ -0,0 +1,176 @@ +From 81b704d3e4674e09781d331df73d76675d5ad8cb Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 14 Jan 2021 19:34:22 +0100 +Subject: ACPI: thermal: Do not call acpi_thermal_check() directly + +From: Rafael J. Wysocki + +commit 81b704d3e4674e09781d331df73d76675d5ad8cb upstream. + +Calling acpi_thermal_check() from acpi_thermal_notify() directly +is problematic if _TMP triggers Notify () on the thermal zone for +which it has been evaluated (which happens on some systems), because +it causes a new acpi_thermal_notify() invocation to be queued up +every time and if that takes place too often, an indefinite number of +pending work items may accumulate in kacpi_notify_wq over time. + +Besides, it is not really useful to queue up a new invocation of +acpi_thermal_check() if one of them is pending already. + +For these reasons, rework acpi_thermal_notify() to queue up a thermal +check instead of calling acpi_thermal_check() directly and only allow +one thermal check to be pending at a time. Moreover, only allow one +acpi_thermal_check_fn() instance at a time to run +thermal_zone_device_update() for one thermal zone and make it return +early if it sees other instances running for the same thermal zone. + +While at it, fold acpi_thermal_check() into acpi_thermal_check_fn(), +as it is only called from there after the other changes made here. + +[This issue appears to have been exposed by commit 6d25be5782e4 + ("sched/core, workqueues: Distangle worker accounting from rq + lock"), but it is unclear why it was not visible earlier.] + +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208877 +Reported-by: Stephen Berman +Diagnosed-by: Sebastian Andrzej Siewior +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Sebastian Andrzej Siewior +Tested-by: Stephen Berman +Cc: All applicable +[bigeasy: Backported to v5.4.y] +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/thermal.c | 55 +++++++++++++++++++++++++++++++++---------------- + 1 file changed, 38 insertions(+), 17 deletions(-) + +--- a/drivers/acpi/thermal.c ++++ b/drivers/acpi/thermal.c +@@ -174,6 +174,8 @@ struct acpi_thermal { + int tz_enabled; + int kelvin_offset; + struct work_struct thermal_check_work; ++ struct mutex thermal_check_lock; ++ refcount_t thermal_check_count; + }; + + /* -------------------------------------------------------------------------- +@@ -494,17 +496,6 @@ static int acpi_thermal_get_trip_points( + return 0; + } + +-static void acpi_thermal_check(void *data) +-{ +- struct acpi_thermal *tz = data; +- +- if (!tz->tz_enabled) +- return; +- +- thermal_zone_device_update(tz->thermal_zone, +- THERMAL_EVENT_UNSPECIFIED); +-} +- + /* sys I/F for generic thermal sysfs support */ + + static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) +@@ -538,6 +529,8 @@ static int thermal_get_mode(struct therm + return 0; + } + ++static void acpi_thermal_check_fn(struct work_struct *work); ++ + static int thermal_set_mode(struct thermal_zone_device *thermal, + enum thermal_device_mode mode) + { +@@ -563,7 +556,7 @@ static int thermal_set_mode(struct therm + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "%s kernel ACPI thermal control\n", + tz->tz_enabled ? "Enable" : "Disable")); +- acpi_thermal_check(tz); ++ acpi_thermal_check_fn(&tz->thermal_check_work); + } + return 0; + } +@@ -932,6 +925,12 @@ static void acpi_thermal_unregister_ther + Driver Interface + -------------------------------------------------------------------------- */ + ++static void acpi_queue_thermal_check(struct acpi_thermal *tz) ++{ ++ if (!work_pending(&tz->thermal_check_work)) ++ queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); ++} ++ + static void acpi_thermal_notify(struct acpi_device *device, u32 event) + { + struct acpi_thermal *tz = acpi_driver_data(device); +@@ -942,17 +941,17 @@ static void acpi_thermal_notify(struct a + + switch (event) { + case ACPI_THERMAL_NOTIFY_TEMPERATURE: +- acpi_thermal_check(tz); ++ acpi_queue_thermal_check(tz); + break; + case ACPI_THERMAL_NOTIFY_THRESHOLDS: + acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); +- acpi_thermal_check(tz); ++ acpi_queue_thermal_check(tz); + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), event, 0); + break; + case ACPI_THERMAL_NOTIFY_DEVICES: + acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); +- acpi_thermal_check(tz); ++ acpi_queue_thermal_check(tz); + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), event, 0); + break; +@@ -1052,7 +1051,27 @@ static void acpi_thermal_check_fn(struct + { + struct acpi_thermal *tz = container_of(work, struct acpi_thermal, + thermal_check_work); +- acpi_thermal_check(tz); ++ ++ if (!tz->tz_enabled) ++ return; ++ /* ++ * In general, it is not sufficient to check the pending bit, because ++ * subsequent instances of this function may be queued after one of them ++ * has started running (e.g. if _TMP sleeps). Avoid bailing out if just ++ * one of them is running, though, because it may have done the actual ++ * check some time ago, so allow at least one of them to block on the ++ * mutex while another one is running the update. ++ */ ++ if (!refcount_dec_not_one(&tz->thermal_check_count)) ++ return; ++ ++ mutex_lock(&tz->thermal_check_lock); ++ ++ thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); ++ ++ refcount_inc(&tz->thermal_check_count); ++ ++ mutex_unlock(&tz->thermal_check_lock); + } + + static int acpi_thermal_add(struct acpi_device *device) +@@ -1084,6 +1103,8 @@ static int acpi_thermal_add(struct acpi_ + if (result) + goto free_memory; + ++ refcount_set(&tz->thermal_check_count, 3); ++ mutex_init(&tz->thermal_check_lock); + INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); + + pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), +@@ -1149,7 +1170,7 @@ static int acpi_thermal_resume(struct de + tz->state.active |= tz->trips.active[i].flags.enabled; + } + +- queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); ++ acpi_queue_thermal_check(tz); + + return AE_OK; + } diff --git a/queue-5.4/arm64-do-not-pass-tagged-addresses-to-__is_lm_address.patch b/queue-5.4/arm64-do-not-pass-tagged-addresses-to-__is_lm_address.patch new file mode 100644 index 00000000000..4c1f362dca9 --- /dev/null +++ b/queue-5.4/arm64-do-not-pass-tagged-addresses-to-__is_lm_address.patch @@ -0,0 +1,53 @@ +From 91cb2c8b072e00632adf463b78b44f123d46a0fa Mon Sep 17 00:00:00 2001 +From: Catalin Marinas +Date: Mon, 1 Feb 2021 19:06:33 +0000 +Subject: arm64: Do not pass tagged addresses to __is_lm_address() + +From: Catalin Marinas + +commit 91cb2c8b072e00632adf463b78b44f123d46a0fa upstream. + +Commit 519ea6f1c82f ("arm64: Fix kernel address detection of +__is_lm_address()") fixed the incorrect validation of addresses below +PAGE_OFFSET. However, it no longer allowed tagged addresses to be passed +to virt_addr_valid(). + +Fix this by explicitly resetting the pointer tag prior to invoking +__is_lm_address(). This is consistent with the __lm_to_phys() macro. + +Fixes: 519ea6f1c82f ("arm64: Fix kernel address detection of __is_lm_address()") +Signed-off-by: Catalin Marinas +Acked-by: Ard Biesheuvel +Cc: # 5.4.x +Cc: Will Deacon +Cc: Vincenzo Frascino +Cc: Mark Rutland +Link: https://lore.kernel.org/r/20210201190634.22942-2-catalin.marinas@arm.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/include/asm/memory.h | 2 +- + arch/arm64/mm/physaddr.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/include/asm/memory.h ++++ b/arch/arm64/include/asm/memory.h +@@ -332,7 +332,7 @@ static inline void *phys_to_virt(phys_ad + #endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */ + + #define virt_addr_valid(addr) ({ \ +- __typeof__(addr) __addr = addr; \ ++ __typeof__(addr) __addr = __tag_reset(addr); \ + __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr)); \ + }) + +--- a/arch/arm64/mm/physaddr.c ++++ b/arch/arm64/mm/physaddr.c +@@ -9,7 +9,7 @@ + + phys_addr_t __virt_to_phys(unsigned long x) + { +- WARN(!__is_lm_address(x), ++ WARN(!__is_lm_address(__tag_reset(x)), + "virt_to_phys used for non-linear address: %pK (%pS)\n", + (void *)x, + (void *)x); diff --git a/queue-5.4/arm64-fix-kernel-address-detection-of-__is_lm_address.patch b/queue-5.4/arm64-fix-kernel-address-detection-of-__is_lm_address.patch new file mode 100644 index 00000000000..8fac39d7a61 --- /dev/null +++ b/queue-5.4/arm64-fix-kernel-address-detection-of-__is_lm_address.patch @@ -0,0 +1,49 @@ +From 519ea6f1c82fcdc9842908155ae379de47818778 Mon Sep 17 00:00:00 2001 +From: Vincenzo Frascino +Date: Tue, 26 Jan 2021 13:40:56 +0000 +Subject: arm64: Fix kernel address detection of __is_lm_address() + +From: Vincenzo Frascino + +commit 519ea6f1c82fcdc9842908155ae379de47818778 upstream. + +Currently, the __is_lm_address() check just masks out the top 12 bits +of the address, but if they are 0, it still yields a true result. +This has as a side effect that virt_addr_valid() returns true even for +invalid virtual addresses (e.g. 0x0). + +Fix the detection checking that it's actually a kernel address starting +at PAGE_OFFSET. + +Fixes: 68dd8ef32162 ("arm64: memory: Fix virt_addr_valid() using __is_lm_address()") +Cc: # 5.4.x +Cc: Will Deacon +Suggested-by: Catalin Marinas +Reviewed-by: Catalin Marinas +Acked-by: Mark Rutland +Signed-off-by: Vincenzo Frascino +Link: https://lore.kernel.org/r/20210126134056.45747-1-vincenzo.frascino@arm.com +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/include/asm/memory.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/arm64/include/asm/memory.h ++++ b/arch/arm64/include/asm/memory.h +@@ -247,11 +247,11 @@ static inline const void *__tag_set(cons + + + /* +- * The linear kernel range starts at the bottom of the virtual address +- * space. Testing the top bit for the start of the region is a +- * sufficient check and avoids having to worry about the tag. ++ * Check whether an arbitrary address is within the linear map, which ++ * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the ++ * kernel's TTBR1 address range. + */ +-#define __is_lm_address(addr) (!(((u64)addr) & BIT(vabits_actual - 1))) ++#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) + + #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) + #define __kimg_to_phys(addr) ((addr) - kimage_voffset) diff --git a/queue-5.4/series b/queue-5.4/series index 5aa3ceb83ed..38cf4853554 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -2,3 +2,7 @@ net-dsa-bcm_sf2-put-device-node-before-return.patch net-switchdev-don-t-set-port_obj_info-handled-true-when-eopnotsupp.patch ibmvnic-ensure-that-crq-entry-read-are-correctly-ordered.patch revert-revert-block-end-bio-with-blk_sts_again-in-case-of-non-mq-devs-and-req_nowait.patch +acpi-thermal-do-not-call-acpi_thermal_check-directly.patch +arm64-fix-kernel-address-detection-of-__is_lm_address.patch +arm64-do-not-pass-tagged-addresses-to-__is_lm_address.patch +tcp-make-tcp_user_timeout-accurate-for-zero-window-probes.patch diff --git a/queue-5.4/tcp-make-tcp_user_timeout-accurate-for-zero-window-probes.patch b/queue-5.4/tcp-make-tcp_user_timeout-accurate-for-zero-window-probes.patch new file mode 100644 index 00000000000..d1345292020 --- /dev/null +++ b/queue-5.4/tcp-make-tcp_user_timeout-accurate-for-zero-window-probes.patch @@ -0,0 +1,92 @@ +From 344db93ae3ee69fc137bd6ed89a8ff1bf5b0db08 Mon Sep 17 00:00:00 2001 +From: Enke Chen +Date: Fri, 22 Jan 2021 11:13:06 -0800 +Subject: tcp: make TCP_USER_TIMEOUT accurate for zero window probes + +From: Enke Chen + +commit 344db93ae3ee69fc137bd6ed89a8ff1bf5b0db08 upstream. + +The TCP_USER_TIMEOUT is checked by the 0-window probe timer. As the +timer has backoff with a max interval of about two minutes, the +actual timeout for TCP_USER_TIMEOUT can be off by up to two minutes. + +In this patch the TCP_USER_TIMEOUT is made more accurate by taking it +into account when computing the timer value for the 0-window probes. + +This patch is similar to and builds on top of the one that made +TCP_USER_TIMEOUT accurate for RTOs in commit b701a99e431d ("tcp: Add +tcp_clamp_rto_to_user_timeout() helper to improve accuracy"). + +Fixes: 9721e709fa68 ("tcp: simplify window probe aborting on USER_TIMEOUT") +Signed-off-by: Enke Chen +Reviewed-by: Neal Cardwell +Signed-off-by: Eric Dumazet +Link: https://lore.kernel.org/r/20210122191306.GA99540@localhost.localdomain +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/net/tcp.h | 1 + + net/ipv4/tcp_input.c | 1 + + net/ipv4/tcp_output.c | 2 ++ + net/ipv4/tcp_timer.c | 18 ++++++++++++++++++ + 4 files changed, 22 insertions(+) + +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -619,6 +619,7 @@ static inline void tcp_clear_xmit_timers + + unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu); + unsigned int tcp_current_mss(struct sock *sk); ++u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when); + + /* Bound MSS / TSO packet size with the half of the window */ + static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3295,6 +3295,7 @@ static void tcp_ack_probe(struct sock *s + } else { + unsigned long when = tcp_probe0_when(sk, TCP_RTO_MAX); + ++ when = tcp_clamp_probe0_to_user_timeout(sk, when); + tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, + when, TCP_RTO_MAX, NULL); + } +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -3850,6 +3850,8 @@ void tcp_send_probe0(struct sock *sk) + */ + timeout = TCP_RESOURCE_PROBE_INTERVAL; + } ++ ++ timeout = tcp_clamp_probe0_to_user_timeout(sk, timeout); + tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, timeout, TCP_RTO_MAX, NULL); + } + +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -40,6 +40,24 @@ static u32 tcp_clamp_rto_to_user_timeout + return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(remaining)); + } + ++u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ u32 remaining; ++ s32 elapsed; ++ ++ if (!icsk->icsk_user_timeout || !icsk->icsk_probes_tstamp) ++ return when; ++ ++ elapsed = tcp_jiffies32 - icsk->icsk_probes_tstamp; ++ if (unlikely(elapsed < 0)) ++ elapsed = 0; ++ remaining = msecs_to_jiffies(icsk->icsk_user_timeout) - elapsed; ++ remaining = max_t(u32, remaining, TCP_TIMEOUT_MIN); ++ ++ return min_t(u32, remaining, when); ++} ++ + /** + * tcp_write_err() - close socket and save error info + * @sk: The socket the error has appeared on. -- 2.47.3