From ce88e1fb2c091ff9207c86b4387c69ee069fd12b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 4 Feb 2026 15:12:48 +0100 Subject: [PATCH] 5.15-stable patches added patches: drm-imx-tve-fix-probe-device-leak.patch mm-kfence-randomize-the-freelist-on-initialization.patch mptcp-avoid-dup-sub_closed-events-after-disconnect.patch pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch team-move-team-device-type-change-at-the-end-of-team_port_add.patch writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch --- .../drm-imx-tve-fix-probe-device-leak.patch | 57 +++++++++ ...omize-the-freelist-on-initialization.patch | 86 +++++++++++++ ...p-sub_closed-events-after-disconnect.patch | 56 +++++++++ ...t-.get_direction-for-the-gpio-driver.patch | 64 ++++++++++ ...mark-the-gpio-controller-as-sleeping.patch | 95 ++++++++++++++ queue-5.15/series | 7 ++ ...e-change-at-the-end-of-team_port_add.patch | 117 ++++++++++++++++++ ...-when-dirtytime_expire_interval-is-0.patch | 77 ++++++++++++ 8 files changed, 559 insertions(+) create mode 100644 queue-5.15/drm-imx-tve-fix-probe-device-leak.patch create mode 100644 queue-5.15/mm-kfence-randomize-the-freelist-on-initialization.patch create mode 100644 queue-5.15/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch create mode 100644 queue-5.15/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch create mode 100644 queue-5.15/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch create mode 100644 queue-5.15/team-move-team-device-type-change-at-the-end-of-team_port_add.patch create mode 100644 queue-5.15/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch diff --git a/queue-5.15/drm-imx-tve-fix-probe-device-leak.patch b/queue-5.15/drm-imx-tve-fix-probe-device-leak.patch new file mode 100644 index 0000000000..f4a217dd7b --- /dev/null +++ b/queue-5.15/drm-imx-tve-fix-probe-device-leak.patch @@ -0,0 +1,57 @@ +From stable+bounces-213319-greg=kroah.com@vger.kernel.org Wed Feb 4 00:50:40 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 18:47:59 -0500 +Subject: drm/imx/tve: fix probe device leak +To: stable@vger.kernel.org +Cc: Johan Hovold , Philipp Zabel , Frank Li , Maxime Ripard , Sasha Levin +Message-ID: <20260203234759.1453100-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit e535c23513c63f02f67e3e09e0787907029efeaf ] + +Make sure to drop the reference taken to the DDC device during probe on +probe failure (e.g. probe deferral) and on driver unbind. + +Fixes: fcbc51e54d2a ("staging: drm/imx: Add support for Television Encoder (TVEv2)") +Cc: stable@vger.kernel.org # 3.10 +Cc: Philipp Zabel +Reviewed-by: Frank Li +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20251030163456.15807-1-johan@kernel.org +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/imx/imx-tve.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/gpu/drm/imx/imx-tve.c ++++ b/drivers/gpu/drm/imx/imx-tve.c +@@ -521,6 +521,13 @@ static const struct component_ops imx_tv + .bind = imx_tve_bind, + }; + ++static void imx_tve_put_device(void *_dev) ++{ ++ struct device *dev = _dev; ++ ++ put_device(dev); ++} ++ + static int imx_tve_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -543,6 +550,12 @@ static int imx_tve_probe(struct platform + if (ddc_node) { + tve->ddc = of_find_i2c_adapter_by_node(ddc_node); + of_node_put(ddc_node); ++ if (tve->ddc) { ++ ret = devm_add_action_or_reset(dev, imx_tve_put_device, ++ &tve->ddc->dev); ++ if (ret) ++ return ret; ++ } + } + + tve->mode = of_get_tve_mode(np); diff --git a/queue-5.15/mm-kfence-randomize-the-freelist-on-initialization.patch b/queue-5.15/mm-kfence-randomize-the-freelist-on-initialization.patch new file mode 100644 index 0000000000..ede798d3e7 --- /dev/null +++ b/queue-5.15/mm-kfence-randomize-the-freelist-on-initialization.patch @@ -0,0 +1,86 @@ +From 870ff19251bf3910dda7a7245da826924045fedd Mon Sep 17 00:00:00 2001 +From: Pimyn Girgis +Date: Tue, 20 Jan 2026 17:15:10 +0100 +Subject: mm/kfence: randomize the freelist on initialization + +From: Pimyn Girgis + +commit 870ff19251bf3910dda7a7245da826924045fedd upstream. + +Randomize the KFENCE freelist during pool initialization to make +allocation patterns less predictable. This is achieved by shuffling the +order in which metadata objects are added to the freelist using +get_random_u32_below(). + +Additionally, ensure the error path correctly calculates the address range +to be reset if initialization fails, as the address increment logic has +been moved to a separate loop. + +Link: https://lkml.kernel.org/r/20260120161510.3289089-1-pimyn@google.com +Fixes: 0ce20dd84089 ("mm: add Kernel Electric-Fence infrastructure") +Signed-off-by: Pimyn Girgis +Reviewed-by: Alexander Potapenko +Cc: Dmitry Vyukov +Cc: Marco Elver +Cc: Ernesto Martnez Garca +Cc: Greg KH +Cc: Kees Cook +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Pimyn Girgis +Signed-off-by: Greg Kroah-Hartman +--- + mm/kfence/core.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +--- a/mm/kfence/core.c ++++ b/mm/kfence/core.c +@@ -520,7 +520,7 @@ static bool __init kfence_init_pool(void + { + unsigned long addr = (unsigned long)__kfence_pool; + struct page *pages; +- int i; ++ int i, rand; + char *p; + + if (!__kfence_pool) +@@ -576,13 +576,28 @@ static bool __init kfence_init_pool(void + INIT_LIST_HEAD(&meta->list); + raw_spin_lock_init(&meta->lock); + meta->state = KFENCE_OBJECT_UNUSED; +- meta->addr = addr; /* Initialize for validation in metadata_to_pageaddr(). */ +- list_add_tail(&meta->list, &kfence_freelist); ++ /* Use addr to randomize the freelist. */ ++ meta->addr = i; + + /* Protect the right redzone. */ +- if (unlikely(!kfence_protect(addr + PAGE_SIZE))) ++ if (unlikely(!kfence_protect(addr + 2 * i * PAGE_SIZE + PAGE_SIZE))) + goto err; ++ } ++ ++ for (i = CONFIG_KFENCE_NUM_OBJECTS; i > 0; i--) { ++ rand = get_random_u32() % i; ++ swap(kfence_metadata[i - 1].addr, kfence_metadata[rand].addr); ++ } ++ ++ for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) { ++ struct kfence_metadata *meta_1 = &kfence_metadata[i]; ++ struct kfence_metadata *meta_2 = &kfence_metadata[meta_1->addr]; ++ ++ list_add_tail(&meta_2->list, &kfence_freelist); ++ } + ++ for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) { ++ kfence_metadata[i].addr = addr; + addr += 2 * PAGE_SIZE; + } + +@@ -597,6 +612,7 @@ static bool __init kfence_init_pool(void + return true; + + err: ++ addr += 2 * i * PAGE_SIZE; + /* + * Only release unprotected pages, and do not try to go back and change + * page attributes due to risk of failing to do so as well. If changing diff --git a/queue-5.15/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch b/queue-5.15/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch new file mode 100644 index 0000000000..2d5ea1b03e --- /dev/null +++ b/queue-5.15/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch @@ -0,0 +1,56 @@ +From stable+bounces-213305-greg=kroah.com@vger.kernel.org Tue Feb 3 21:20:06 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 15:20:00 -0500 +Subject: mptcp: avoid dup SUB_CLOSED events after disconnect +To: stable@vger.kernel.org +Cc: "Matthieu Baerts (NGI0)" , Marco Angaroni , Geliang Tang , Jakub Kicinski , Sasha Levin +Message-ID: <20260203202000.1387755-1-sashal@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +[ Upstream commit 280d654324e33f8e6e3641f76764694c7b64c5db ] + +In case of subflow disconnect(), which can also happen with the first +subflow in case of errors like timeout or reset, mptcp_subflow_ctx_reset +will reset most fields from the mptcp_subflow_context structure, +including close_event_done. Then, when another subflow is closed, yet +another SUB_CLOSED event for the disconnected initial subflow is sent. +Because of the previous reset, there are no source address and +destination port. + +A solution is then to also check the subflow's local id: it shouldn't be +negative anyway. + +Another solution would be not to reset subflow->close_event_done at +disconnect time, but when reused. But then, probably the whole reset +could be done when being reused. Let's not change this logic, similar +to TCP with tcp_disconnect(). + +Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events") +Cc: stable@vger.kernel.org +Reported-by: Marco Angaroni +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/603 +Reviewed-by: Geliang Tang +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-1-7f71e1bc4feb@kernel.org +Signed-off-by: Jakub Kicinski +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2398,8 +2398,8 @@ static void __mptcp_close_ssk(struct soc + void mptcp_close_ssk(struct sock *sk, struct sock *ssk, + struct mptcp_subflow_context *subflow) + { +- /* The first subflow can already be closed and still in the list */ +- if (subflow->close_event_done) ++ /* The first subflow can already be closed or disconnected */ ++ if (subflow->close_event_done || READ_ONCE(subflow->local_id) < 0) + return; + + subflow->close_event_done = true; diff --git a/queue-5.15/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch b/queue-5.15/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch new file mode 100644 index 0000000000..e96c833f45 --- /dev/null +++ b/queue-5.15/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch @@ -0,0 +1,64 @@ +From stable+bounces-213321-greg=kroah.com@vger.kernel.org Wed Feb 4 01:02:21 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 19:02:13 -0500 +Subject: pinctrl: lpass-lpi: implement .get_direction() for the GPIO driver +To: stable@vger.kernel.org +Cc: Bartosz Golaszewski , Abel Vesa , Konrad Dybcio , Abel Vesa , Linus Walleij , Sasha Levin +Message-ID: <20260204000213.1456166-1-sashal@kernel.org> + +From: Bartosz Golaszewski + +[ Upstream commit 4f0d22ec60cee420125f4055af76caa0f373a3fe ] + +GPIO controller driver should typically implement the .get_direction() +callback as GPIOLIB internals may try to use it to determine the state +of a pin. Add it for the LPASS LPI driver. + +Reported-by: Abel Vesa +Cc: stable@vger.kernel.org +Fixes: 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver") +Signed-off-by: Bartosz Golaszewski +Reviewed-by: Konrad Dybcio +Tested-by: Konrad Dybcio # X1E CRD +Tested-by: Abel Vesa +Signed-off-by: Linus Walleij +[ PIN_CONFIG_LEVEL => PIN_CONFIG_OUTPUT ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c ++++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +@@ -484,6 +484,22 @@ static const struct pinconf_ops lpi_gpio + .pin_config_group_set = lpi_config_set, + }; + ++static int lpi_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ unsigned long config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, 0); ++ struct lpi_pinctrl *state = gpiochip_get_data(chip); ++ unsigned long arg; ++ int ret; ++ ++ ret = lpi_config_get(state->ctrl, pin, &config); ++ if (ret) ++ return ret; ++ ++ arg = pinconf_to_config_argument(config); ++ ++ return arg ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; ++} ++ + static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) + { + struct lpi_pinctrl *state = gpiochip_get_data(chip); +@@ -582,6 +598,7 @@ static void lpi_gpio_dbg_show(struct seq + #endif + + static const struct gpio_chip lpi_gpio_template = { ++ .get_direction = lpi_gpio_get_direction, + .direction_input = lpi_gpio_direction_input, + .direction_output = lpi_gpio_direction_output, + .get = lpi_gpio_get, diff --git a/queue-5.15/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch b/queue-5.15/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch new file mode 100644 index 0000000000..b740f4b582 --- /dev/null +++ b/queue-5.15/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch @@ -0,0 +1,95 @@ +From stable+bounces-213272-greg=kroah.com@vger.kernel.org Tue Feb 3 17:21:20 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:12:34 -0500 +Subject: pinctrl: meson: mark the GPIO controller as sleeping +To: stable@vger.kernel.org +Cc: Bartosz Golaszewski , Marek Szyprowski , Martin Blumenstingl , Neil Armstrong , Linus Walleij , Sasha Levin +Message-ID: <20260203161234.1303241-1-sashal@kernel.org> + +From: Bartosz Golaszewski + +[ Upstream commit 28f24068387169722b508bba6b5257cb68b86e74 ] + +The GPIO controller is configured as non-sleeping but it uses generic +pinctrl helpers which use a mutex for synchronization. + +This can cause the following lockdep splat with shared GPIOs enabled on +boards which have multiple devices using the same GPIO: + +BUG: sleeping function called from invalid context at +kernel/locking/mutex.c:591 +in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 142, name: +kworker/u25:3 +preempt_count: 1, expected: 0 +RCU nest depth: 0, expected: 0 +INFO: lockdep is turned off. +irq event stamp: 46379 +hardirqs last enabled at (46379): [] +_raw_spin_unlock_irqrestore+0x74/0x78 +hardirqs last disabled at (46378): [] +_raw_spin_lock_irqsave+0x84/0x88 +softirqs last enabled at (46330): [] +handle_softirqs+0x4c4/0x4dc +softirqs last disabled at (46295): [] +__do_softirq+0x14/0x20 +CPU: 1 UID: 0 PID: 142 Comm: kworker/u25:3 Tainted: G C +6.19.0-rc4-next-20260105+ #11963 PREEMPT +Tainted: [C]=CRAP +Hardware name: Khadas VIM3 (DT) +Workqueue: events_unbound deferred_probe_work_func +Call trace: + show_stack+0x18/0x24 (C) + dump_stack_lvl+0x90/0xd0 + dump_stack+0x18/0x24 + __might_resched+0x144/0x248 + __might_sleep+0x48/0x98 + __mutex_lock+0x5c/0x894 + mutex_lock_nested+0x24/0x30 + pinctrl_get_device_gpio_range+0x44/0x128 + pinctrl_gpio_set_config+0x40/0xdc + gpiochip_generic_config+0x28/0x3c + gpio_do_set_config+0xa8/0x194 + gpiod_set_config+0x34/0xfc + gpio_shared_proxy_set_config+0x6c/0xfc [gpio_shared_proxy] + gpio_do_set_config+0xa8/0x194 + gpiod_set_transitory+0x4c/0xf0 + gpiod_configure_flags+0xa4/0x480 + gpiod_find_and_request+0x1a0/0x574 + gpiod_get_index+0x58/0x84 + devm_gpiod_get_index+0x20/0xb4 + devm_gpiod_get+0x18/0x24 + mmc_pwrseq_emmc_probe+0x40/0xb8 + platform_probe+0x5c/0xac + really_probe+0xbc/0x298 + __driver_probe_device+0x78/0x12c + driver_probe_device+0xdc/0x164 + __device_attach_driver+0xb8/0x138 + bus_for_each_drv+0x80/0xdc + __device_attach+0xa8/0x1b0 + +Fixes: 6ac730951104 ("pinctrl: add driver for Amlogic Meson SoCs") +Cc: stable@vger.kernel.org +Reported-by: Marek Szyprowski +Closes: https://lore.kernel.org/all/00107523-7737-4b92-a785-14ce4e93b8cb@samsung.com/ +Signed-off-by: Bartosz Golaszewski +Reviewed-by: Martin Blumenstingl +Reviewed-by: Neil Armstrong +Signed-off-by: Linus Walleij +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/meson/pinctrl-meson.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pinctrl/meson/pinctrl-meson.c ++++ b/drivers/pinctrl/meson/pinctrl-meson.c +@@ -617,7 +617,7 @@ static int meson_gpiolib_register(struct + pc->chip.set = meson_gpio_set; + pc->chip.base = -1; + pc->chip.ngpio = pc->data->num_pins; +- pc->chip.can_sleep = false; ++ pc->chip.can_sleep = true; + pc->chip.of_node = pc->of_node; + pc->chip.of_gpio_n_cells = 2; + diff --git a/queue-5.15/series b/queue-5.15/series index e2d9092d93..16172d867c 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -192,3 +192,10 @@ can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch btrfs-prevent-use-after-free-on-page-private-data-in-btrfs_subpage_clear_uptodate.patch net-sched-act_ife-convert-comma-to-semicolon.patch +mm-kfence-randomize-the-freelist-on-initialization.patch +pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch +drm-imx-tve-fix-probe-device-leak.patch +writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch +mptcp-avoid-dup-sub_closed-events-after-disconnect.patch +pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch +team-move-team-device-type-change-at-the-end-of-team_port_add.patch diff --git a/queue-5.15/team-move-team-device-type-change-at-the-end-of-team_port_add.patch b/queue-5.15/team-move-team-device-type-change-at-the-end-of-team_port_add.patch new file mode 100644 index 0000000000..451e844868 --- /dev/null +++ b/queue-5.15/team-move-team-device-type-change-at-the-end-of-team_port_add.patch @@ -0,0 +1,117 @@ +From stable+bounces-213352-greg=kroah.com@vger.kernel.org Wed Feb 4 07:07:11 2026 +From: Rahul Sharma +Date: Wed, 4 Feb 2026 14:06:24 +0800 +Subject: team: Move team device type change at the end of team_port_add +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, "Nikola Z. Ivanov" , syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com, Jiri Pirko , Jakub Kicinski , Rahul Sharma +Message-ID: <20260204060624.1367679-1-black.hawk@163.com> + +From: "Nikola Z. Ivanov" + +[ Upstream commit 0ae9cfc454ea5ead5f3ddbdfe2e70270d8e2c8ef ] + +Attempting to add a port device that is already up will expectedly fail, +but not before modifying the team device header_ops. + +In the case of the syzbot reproducer the gre0 device is +already in state UP when it attempts to add it as a +port device of team0, this fails but before that +header_ops->create of team0 is changed from eth_header to ipgre_header +in the call to team_dev_type_check_change. + +Later when we end up in ipgre_header() struct ip_tunnel* points to nonsense +as the private data of the device still holds a struct team. + +Example sequence of iproute2 commands to reproduce the hang/BUG(): +ip link add dev team0 type team +ip link add dev gre0 type gre +ip link set dev gre0 up +ip link set dev gre0 master team0 +ip link set dev team0 up +ping -I team0 1.1.1.1 + +Move team_dev_type_check_change down where all other checks have passed +as it changes the dev type with no way to restore it in case +one of the checks that follow it fail. + +Also make sure to preserve the origial mtu assignment: + - If port_dev is not the same type as dev, dev takes mtu from port_dev + - If port_dev is the same type as dev, port_dev takes mtu from dev + +This is done by adding a conditional before the call to dev_set_mtu +to prevent it from assigning port_dev->mtu = dev->mtu and instead +letting team_dev_type_check_change assign dev->mtu = port_dev->mtu. +The conditional is needed because the patch moves the call to +team_dev_type_check_change past dev_set_mtu. + +Testing: + - team device driver in-tree selftests + - Add/remove various devices as slaves of team device + - syzbot + +Reported-by: syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=a2a3b519de727b0f7903 +Fixes: 1d76efe1577b ("team: add support for non-ethernet devices") +Signed-off-by: Nikola Z. Ivanov +Reviewed-by: Jiri Pirko +Link: https://patch.msgid.link/20251122002027.695151-1-zlatistiv@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/team/team.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1181,10 +1181,6 @@ static int team_port_add(struct team *te + return -EPERM; + } + +- err = team_dev_type_check_change(dev, port_dev); +- if (err) +- return err; +- + if (port_dev->flags & IFF_UP) { + NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port"); + netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n", +@@ -1202,10 +1198,16 @@ static int team_port_add(struct team *te + INIT_LIST_HEAD(&port->qom_list); + + port->orig.mtu = port_dev->mtu; +- err = dev_set_mtu(port_dev, dev->mtu); +- if (err) { +- netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); +- goto err_set_mtu; ++ /* ++ * MTU assignment will be handled in team_dev_type_check_change ++ * if dev and port_dev are of different types ++ */ ++ if (dev->type == port_dev->type) { ++ err = dev_set_mtu(port_dev, dev->mtu); ++ if (err) { ++ netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); ++ goto err_set_mtu; ++ } + } + + memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len); +@@ -1280,6 +1282,10 @@ static int team_port_add(struct team *te + } + } + ++ err = team_dev_type_check_change(dev, port_dev); ++ if (err) ++ goto err_set_dev_type; ++ + if (dev->flags & IFF_UP) { + netif_addr_lock_bh(dev); + dev_uc_sync_multiple(port_dev, dev); +@@ -1298,6 +1304,7 @@ static int team_port_add(struct team *te + + return 0; + ++err_set_dev_type: + err_set_slave_promisc: + __team_option_inst_del_port(team, port); + diff --git a/queue-5.15/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch b/queue-5.15/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch new file mode 100644 index 0000000000..d5640a1abd --- /dev/null +++ b/queue-5.15/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch @@ -0,0 +1,77 @@ +From stable+bounces-213306-greg=kroah.com@vger.kernel.org Tue Feb 3 21:27:33 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 15:26:57 -0500 +Subject: writeback: fix 100% CPU usage when dirtytime_expire_interval is 0 +To: stable@vger.kernel.org +Cc: Laveesh Bansal , Jan Kara , Christian Brauner , Sasha Levin +Message-ID: <20260203202657.1391505-1-sashal@kernel.org> + +From: Laveesh Bansal + +[ Upstream commit 543467d6fe97e27e22a26e367fda972dbefebbff ] + +When vm.dirtytime_expire_seconds is set to 0, wakeup_dirtytime_writeback() +schedules delayed work with a delay of 0, causing immediate execution. +The function then reschedules itself with 0 delay again, creating an +infinite busy loop that causes 100% kworker CPU usage. + +Fix by: +- Only scheduling delayed work in wakeup_dirtytime_writeback() when + dirtytime_expire_interval is non-zero +- Cancelling the delayed work in dirtytime_interval_handler() when + the interval is set to 0 +- Adding a guard in start_dirtytime_writeback() for defensive coding + +Tested by booting kernel in QEMU with virtme-ng: +- Before fix: kworker CPU spikes to ~73% +- After fix: CPU remains at normal levels +- Setting interval back to non-zero correctly resumes writeback + +Fixes: a2f4870697a5 ("fs: make sure the timestamps for lazytime inodes eventually get written") +Cc: stable@vger.kernel.org +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220227 +Signed-off-by: Laveesh Bansal +Link: https://patch.msgid.link/20260106145059.543282-2-laveeshb@laveeshbansal.com +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +[ adapted system_percpu_wq to system_wq for the workqueue used in dirtytime_interval_handler() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/fs-writeback.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -2391,12 +2391,14 @@ static void wakeup_dirtytime_writeback(s + wb_wakeup(wb); + } + rcu_read_unlock(); +- schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); ++ if (dirtytime_expire_interval) ++ schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + } + + static int __init start_dirtytime_writeback(void) + { +- schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); ++ if (dirtytime_expire_interval) ++ schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + return 0; + } + __initcall(start_dirtytime_writeback); +@@ -2407,8 +2409,12 @@ int dirtytime_interval_handler(struct ct + int ret; + + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +- if (ret == 0 && write) +- mod_delayed_work(system_wq, &dirtytime_work, 0); ++ if (ret == 0 && write) { ++ if (dirtytime_expire_interval) ++ mod_delayed_work(system_wq, &dirtytime_work, 0); ++ else ++ cancel_delayed_work_sync(&dirtytime_work); ++ } + return ret; + } + -- 2.47.3