6.16.4-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 418/457 net/mlx5: HWS, Fix table creation UID
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Vesker <[email protected]>
[ Upstream commit 8a51507320ebddaab32610199774f69cd7d53e78 ]
During table creation, caller passes a UID using ft_attr. The UID value was ignored, which leads to problems when the caller sets the UID to a non-zero value, such as SHARED_RESOURCE_UID (0xffff) - the internal FT objects will be created with UID=0.
--- .../ethernet/mellanox/mlx5/core/steering/hws/cmd.c | 1 + .../ethernet/mellanox/mlx5/core/steering/hws/cmd.h | 1 + .../mellanox/mlx5/core/steering/hws/fs_hws.c | 1 + .../mellanox/mlx5/core/steering/hws/matcher.c | 5 ++++- .../mellanox/mlx5/core/steering/hws/mlx5hws.h | 1 + .../mellanox/mlx5/core/steering/hws/table.c | 13 ++++++++++--- .../mellanox/mlx5/core/steering/hws/table.h | 3 ++- 7 files changed, 20 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c +1 -0
@@ -55,6 +55,7 @@ int mlx5hws_cmd_flow_table_create(struct mlx5_core_dev *mdev,MLX5_SET (create_flow_table_in, in, opcode,MLX5_CMD_OP_CREATE_FLOW_TABLE );MLX5_SET (create_flow_table_in, in, table_type, ft_attr->type); +MLX5_SET (create_flow_table_in, in, uid, ft_attr->uid); ft_ctx =MLX5_ADDR_OF (create_flow_table_in, in, flow_table_context);MLX5_SET (flow_table_context, ft_ctx, level, ft_attr->level);
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.h +1 -0
@@ -36,6 +36,7 @@ struct mlx5hws_cmd_set_fte_attr {struct mlx5hws_cmd_ft_create_attr {u8 type;u8 level; +u16 uid;bool rtc_valid;bool decap_en;bool reformat_en;
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c +1 -0
@@ -267,6 +267,7 @@ static int mlx5_cmd_hws_create_flow_table(struct mlx5_flow_root_namespace *ns, tbl_attr.type =MLX5HWS_TABLE_TYPE_FDB ; tbl_attr.level = ft_attr->level; + tbl_attr.uid = ft_attr->uid; tbl =mlx5hws_table_create (ctx, &tbl_attr);if (!tbl) {mlx5_core_err (ns->dev,"Failed creating hws flow_table\n" );
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c +4 -1
@@ -85,6 +85,7 @@ static int hws_matcher_create_end_ft_isolated(struct mlx5hws_matcher *matcher) ret =mlx5hws_table_create_default_ft (tbl->ctx->mdev, tbl, +0 , &matcher->end_ft_id);if (ret) {mlx5hws_err (tbl->ctx,"Isolated matcher: failed to create end flow table\n" );
@@ -112,7 +113,9 @@ static int hws_matcher_create_end_ft(struct mlx5hws_matcher *matcher)if (mlx5hws_matcher_is_isolated (matcher)) ret =hws_matcher_create_end_ft_isolated (matcher);else - ret =mlx5hws_table_create_default_ft (tbl->ctx->mdev, tbl, + ret =mlx5hws_table_create_default_ft (tbl->ctx->mdev, + tbl, +0 , &matcher->end_ft_id);if (ret) {
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws.h +1 -0
@@ -75,6 +75,7 @@ struct mlx5hws_context_attr {struct mlx5hws_table_attr {enum mlx5hws_table_type type;u32 level; +u16 uid; };enum mlx5hws_matcher_flow_src {
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c +10 -3
@@ -9,6 +9,7 @@ u32 mlx5hws_table_get_id(struct mlx5hws_table *tbl) }static void hws_table_init_next_ft_attr (struct mlx5hws_table *tbl, +u16 uid,struct mlx5hws_cmd_ft_create_attr *ft_attr) { ft_attr->type = tbl->fw_ft_type;
@@ -16,7 +17,9 @@ static void hws_table_init_next_ft_attr(struct mlx5hws_table *tbl, ft_attr->level = tbl->ctx->caps->fdb_ft.max_level -1 ; else ft_attr->level = tbl->ctx->caps->nic_ft.max_level - 1; + ft_attr->rtc_valid = true; + ft_attr->uid = uid; } static void hws_table_set_cap_attr(struct mlx5hws_table *tbl,
@@ -119,12 +122,12 @@ static int hws_table_connect_to_default_miss_tbl(struct mlx5hws_table *tbl, u32int mlx5hws_table_create_default_ft (struct mlx5_core_dev *mdev,struct mlx5hws_table *tbl, -u32 *ft_id) +u16 uid,u32 *ft_id) {struct mlx5hws_cmd_ft_create_attr ft_attr = {0 };int ret; -hws_table_init_next_ft_attr (tbl, &ft_attr); +hws_table_init_next_ft_attr (tbl, uid, &ft_attr);hws_table_set_cap_attr (tbl, &ft_attr); ret =mlx5hws_cmd_flow_table_create (mdev, &ft_attr, ft_id);
@@ -189,7 +192,10 @@ static int hws_table_init(struct mlx5hws_table *tbl) }mutex_lock (&ctx->ctrl_lock); - ret =mlx5hws_table_create_default_ft (tbl->ctx->mdev, tbl, &tbl->ft_id); + ret =mlx5hws_table_create_default_ft (tbl->ctx->mdev, + tbl, + tbl->uid, + &tbl->ft_id);if (ret) {mlx5hws_err (tbl->ctx,"Failed to create flow table object\n" );mutex_unlock (&ctx->ctrl_lock);
@@ -239,6 +245,7 @@ struct mlx5hws_table *mlx5hws_table_create(struct mlx5hws_context *ctx, tbl->ctx = ctx; tbl->type = attr->type; tbl->level = attr->level; + tbl->uid = attr->uid; ret =hws_table_init (tbl);if (ret) {
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.h +2 -1
@@ -18,6 +18,7 @@ struct mlx5hws_table {enum mlx5hws_table_type type;u32 fw_ft_type;u32 level; +u16 uid;struct list_head matchers_list;struct list_head tbl_list_node;struct mlx5hws_default_miss default_miss;
@@ -47,7 +48,7 @@ u32 mlx5hws_table_get_res_fw_ft_type(enum mlx5hws_table_type tbl_type,int mlx5hws_table_create_default_ft (struct mlx5_core_dev *mdev,struct mlx5hws_table *tbl, -u32 *ft_id); +u16 uid,u32 *ft_id);void mlx5hws_table_destroy_default_ft (struct mlx5hws_table *tbl,u32 ft_id);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 419/457 net/mlx5: CT: Use the correct counter offset
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlad Dogaru <[email protected]>
[ Upstream commit d2d6f950cb43be6845a41cac5956cb2a10e657e5 ]
Specifying the counter action is not enough, as it is used by multiple counters that were allocated in a bulk. By omitting the offset, rules will be associated with a different counter from the same bulk. Subsequently, the CT subsystem checks the correct counter, assumes that no traffic has triggered the rule, and ages out the rule. The end result is intermittent offloading of long lived connections, as rules are aged out then promptly re-added.
Fix this by specifying the correct offset along with the counter rule.
--- drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c +2 -0
@@ -173,6 +173,8 @@ static void mlx5_ct_fs_hmfs_fill_rule_actions(struct mlx5_ct_fs_hmfs *fs_hmfs,memset (rule_actions,0 ,NUM_CT_HMFS_RULES *sizeof (*rule_actions)); rule_actions[0 ].action =mlx5_fc_get_hws_action (fs_hmfs->ctx, attr->counter); + rule_actions[0 ].counter.offset = + attr->counter->id - attr->counter->bulk->base_id;/* Modify header is special, it may require extra arguments outside the action itself. */ if (mh_action->mh_data) { rule_actions[1 ].modify_header.offset = mh_action->mh_data->offset;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 420/457 microchip: lan865x: fix missing netif_start_queue() call on device open
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Parthiban Veerasooran <[email protected]>
[ Upstream commit 1683fd1b2fa79864d3c7a951d9cea0a9ba1a1923 ]
This fixes an issue where the transmit queue is started implicitly only the very first time the device is registered. When the device is taken down and brought back up again (using ip or ifconfig), the transmit queue is not restarted, causing packet transmission to hang.
Adding an explicit call to netif_start_queue() in lan865x_net_open() ensures the transmit queue is properly started every time the device is reopened.
--- drivers/net/ethernet/microchip/lan865x/lan865x.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/microchip/lan865x/lan865x.c +2 -0
@@ -311,6 +311,8 @@ static int lan865x_net_open(struct net_device *netdev)phy_start (netdev->phydev); +netif_start_queue (netdev); +return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 421/457 microchip: lan865x: fix missing Timer Increment config for Rev.B0/B1
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Parthiban Veerasooran <[email protected]>
[ Upstream commit 2cd58fec912acec273cb155911ab8f06ddbb131a ]
Fix missing configuration for LAN865x silicon revisions B0 and B1 as per Microchip Application Note AN1760 (Rev F, June 2024).
The Timer Increment register was not being set, which is required for accurate timestamping. As per the application note, configure the MAC to set timestamping at the end of the Start of Frame Delimiter (SFD), and set the Timer Increment register to 40 ns (corresponding to a 25 MHz internal clock).
--- .../net/ethernet/microchip/lan865x/lan865x.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/net/ethernet/microchip/lan865x/lan865x.c +19 -0
@@ -32,6 +32,10 @@/* MAC Specific Addr 1 Top Reg */ #define LAN865X_REG_MAC_H_SADDR1 0x00010023 +/* MAC TSU Timer Increment Register */ +#define LAN865X_REG_MAC_TSU_TIMER_INCR 0x00010077 +#define MAC_TSU_TIMER_INCR_COUNT_NANOSECONDS 0x0028 +struct lan865x_priv {struct work_struct multicast_work;struct net_device *netdev;
@@ -346,6 +350,21 @@ static int lan865x_probe(struct spi_device *spi) goto free_netdev; } +/* LAN865x Rev.B0/B1 configuration parameters from AN1760 +* As per the Configuration Application Note AN1760 published in the +* link, https://www.microchip.com/en-us/application-notes/an1760 +* Revision F (DS60001760G - June 2024), configure the MAC to set time +* stamping at the end of the Start of Frame Delimiter (SFD) and set the +* Timer Increment reg to 40 ns to be used as a 25 MHz internal clock. +*/ + ret =oa_tc6_write_register (priv->tc6,LAN865X_REG_MAC_TSU_TIMER_INCR , +MAC_TSU_TIMER_INCR_COUNT_NANOSECONDS ); +if (ret) { +dev_err (&spi->dev,"Failed to config TSU Timer Incr reg: %d\n" , + ret); + goto oa_tc6_exit; + } +/* As per the point s3 in the below errata, SPI receive Ethernet frame * transfer may halt when starting the next frame in the same data block * (chunk) as the end of a previous frame. The RFA field should be
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 422/457 objtool/LoongArch: Get table size correctly if LTO is enabled
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
[ Upstream commit a47bc954cf0eb51f2828e1607d169d487df7f11f ]
When compiling with LLVM and CONFIG_LTO_CLANG is set, there exist many objtool warnings "sibling call from callable instruction with modified stack frame".
For this special case, the related object file shows that there is no generated relocation section '.rela.discard.tablejump_annotate' for the table jump instruction jirl, thus objtool can not know that what is the actual destination address.
It needs to do something on the LLVM side to make sure that there is the relocation section '.rela.discard.tablejump_annotate' if LTO is enabled, but in order to maintain compatibility for the current LLVM compiler, this can be done in the kernel Makefile for now. Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' needs to be passed via '-mllvm' to ld.lld.
Before doing the above changes, it should handle the special case of the relocation section '.rela.discard.tablejump_annotate' to get the correct table size first, otherwise there are many objtool warnings and errors if LTO is enabled.
There are many different rodata for each function if LTO is enabled, it is necessary to enhance get_rodata_table_size_by_table_annotate().
--- tools/objtool/arch/loongarch/special.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
tools/objtool/arch/loongarch/special.c +23 -0
@@ -27,6 +27,7 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,struct table_info *next_table;unsigned long tmp_insn_offset;unsigned long tmp_rodata_offset; +bool is_valid_list = false; rsec =find_section_by_name (file->elf,".rela.discard.tablejump_annotate" );if (!rsec)
@@ -35,6 +36,12 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,INIT_LIST_HEAD (&table_list);for_each_reloc (rsec, reloc) { +if (reloc->sym->sec->rodata) +continue ; + +if (strcmp (insn->sec->name, reloc->sym->sec->name)) +continue ; + orig_table =malloc (sizeof (struct table_info ));if (!orig_table) {WARN ("malloc failed" );
@@ -49,6 +56,22 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,if (reloc_idx (reloc) +1 ==sec_num_entries (rsec))break ; + +if (strcmp (insn->sec->name, (reloc +1 )->sym->sec->name)) { +list_for_each_entry (orig_table, &table_list, jump_info) { +if (orig_table->insn_offset == insn->offset) { + is_valid_list = true; +break ; + } + } + +if (!is_valid_list) { +list_del_init (&table_list); +continue ; + } + +break ; + } }list_for_each_entry (orig_table, &table_list, jump_info) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 423/457 LoongArch: Pass annotate-tablejump option if LTO is enabled
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
[ Upstream commit 5dfea6644d201bfeffaa7e0d79d62309856613b7 ]
When compiling with LLVM and CONFIG_LTO_CLANG is set, there exist many objtool warnings "sibling call from callable instruction with modified stack frame".
For this special case, the related object file shows that there is no generated relocation section '.rela.discard.tablejump_annotate' for the table jump instruction jirl, thus objtool can not know that what is the actual destination address.
It needs to do something on the LLVM side to make sure that there is the relocation section '.rela.discard.tablejump_annotate' if LTO is enabled, but in order to maintain compatibility for the current LLVM compiler, this can be done in the kernel Makefile for now. Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' needs to be passed via '-mllvm' to ld.lld.
Note that it should also pass the compiler option -mannotate-tablejump rather than only pass '-mllvm --loongarch-annotate-tablejump' to ld.lld if LTO is enabled, otherwise there are no jump info for some table jump instructions.
--- arch/loongarch/Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
arch/loongarch/Makefile +6 -0
@@ -102,7 +102,13 @@ KBUILD_CFLAGS += $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma) ifdef CONFIG_OBJTOOL ifdef CONFIG_CC_HAS_ANNOTATE_TABLEJUMP +# The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled. +# Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' also needs to +# be passed via '-mllvm' to ld.lld. KBUILD_CFLAGS += -mannotate-tablejump +ifdef CONFIG_LTO_CLANG +KBUILD_LDFLAGS += -mllvm --loongarch-annotate-tablejump +endif else KBUILD_CFLAGS += -fno-jump-tables # keep compatibility with older compilers endif
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 424/457 LoongArch: Optimize module load time by optimizing PLT/GOT counting
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kanglong Wang <[email protected]>
[ Upstream commit 63dbd8fb2af3a89466538599a9acb2d11ef65c06 ]
When enabling CONFIG_KASAN, CONFIG_PREEMPT_VOLUNTARY_BUILD and CONFIG_PREEMPT_VOLUNTARY at the same time, there will be soft deadlock, the relevant logs are as follows:
rcu: INFO: rcu_sched self-detected stall on CPU ... Call Trace: [<900000000024f9e4>] show_stack+0x5c/0x180 [<90000000002482f4>] dump_stack_lvl+0x94/0xbc [<9000000000224544>] rcu_dump_cpu_stacks+0x1fc/0x280 [<900000000037ac80>] rcu_sched_clock_irq+0x720/0xf88 [<9000000000396c34>] update_process_times+0xb4/0x150 [<90000000003b2474>] tick_nohz_handler+0xf4/0x250 [<9000000000397e28>] __hrtimer_run_queues+0x1d0/0x428 [<9000000000399b2c>] hrtimer_interrupt+0x214/0x538 [<9000000000253634>] constant_timer_interrupt+0x64/0x80 [<9000000000349938>] __handle_irq_event_percpu+0x78/0x1a0 [<9000000000349a78>] handle_irq_event_percpu+0x18/0x88 [<9000000000354c00>] handle_percpu_irq+0x90/0xf0 [<9000000000348c74>] handle_irq_desc+0x94/0xb8 [<9000000001012b28>] handle_cpu_irq+0x68/0xa0 [<9000000001def8c0>] handle_loongarch_irq+0x30/0x48 [<9000000001def958>] do_vint+0x80/0xd0 [<9000000000268a0c>] kasan_mem_to_shadow.part.0+0x2c/0x2a0 [<90000000006344f4>] __asan_load8+0x4c/0x120 [<900000000025c0d0>] module_frob_arch_sections+0x5c8/0x6b8 [<90000000003895f0>] load_module+0x9e0/0x2958 [<900000000038b770>] __do_sys_init_module+0x208/0x2d0 [<9000000001df0c34>] do_syscall+0x94/0x190 [<900000000024d6fc>] handle_syscall+0xbc/0x158
After analysis, this is because the slow speed of loading the amdgpu module leads to the long time occupation of the cpu and then the soft deadlock.
When loading a module, module_frob_arch_sections() tries to figure out the number of PLTs/GOTs that will be needed to handle all the RELAs. It will call the count_max_entries() to find in an out-of-order date which counting algorithm has O(n^2) complexity.
To make it faster, we sort the relocation list by info and addend. That way, to check for a duplicate relocation, it just needs to compare with the previous entry. This reduces the complexity of the algorithm to O(n
log n), as done in commit d4e0340919fb ("arm64/module: Optimize module
load time by optimizing PLT counting"). This gives sinificant reduction in module load time for modules with large number of relocations.
After applying this patch, the soft deadlock problem has been solved, and the kernel starts normally without "Call Trace".
Using the default configuration to test some modules, the results are as follows:
Module Size ip_tables 36K fat 143K radeon 2.5MB amdgpu 16MB
Without this patch:
Module Module load time (ms) Count(PLTs/GOTs) ip_tables 18 59/6 fat 0 162/14 radeon 54 1221/84 amdgpu 1411 4525/1098
With this patch:
Module Module load time (ms) Count(PLTs/GOTs) ip_tables 18 59/6 fat 0 162/14 radeon 22 1221/84 amdgpu 45 4525/1098
--- arch/loongarch/kernel/module-sections.c | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-)
arch/loongarch/kernel/module-sections.c +18 -18
@@ -8,6 +8,7 @@#include <linux/module.h> #include <linux/moduleloader.h> #include <linux/ftrace.h> +#include <linux/sort.h> Elf_Addr module_emit_got_entry (struct module *mod,Elf_Shdr *sechdrs,Elf_Addr val) {
@@ -61,39 +62,38 @@ Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr vreturn (Elf_Addr)&plt[nr]; } -static int is_rela_equal (const Elf_Rela *x,const Elf_Rela *y) -{ -return x->r_info == y->r_info && x->r_addend == y->r_addend; -} +#define cmp_3way (a, b) ((a) < (b) ? -1 : (a) > (b)) -static bool duplicate_rela (const Elf_Rela *rela,int idx) +static int compare_rela (const void *x,const void *y) { -int i; +int ret; +const Elf_Rela *rela_x = x, *rela_y = y; -for (i =0 ; i < idx; i++) { -if (is_rela_equal (&rela[i], &rela[idx])) -return true; - } + ret =cmp_3way (rela_x->r_info, rela_y->r_info); +if (ret ==0 ) + ret =cmp_3way (rela_x->r_addend, rela_y->r_addend); -return false; +return ret; }static void count_max_entries (Elf_Rela *relas,int num,unsigned int *plts,unsigned int *gots) { -unsigned int i, type; +unsigned int i; + +sort (relas, num,sizeof (Elf_Rela), compare_rela,NULL );for (i =0 ; i < num; i++) { - type =ELF_R_TYPE (relas[i].r_info); -switch (type) { +if (i && !compare_rela (&relas[i-1 ], &relas[i])) +continue ; + +switch (ELF_R_TYPE (relas[i].r_info)) {case R_LARCH_SOP_PUSH_PLT_PCREL :case R_LARCH_B26 : -if (!duplicate_rela (relas, i)) - (*plts)++; + (*plts)++;break ;case R_LARCH_GOT_PC_HI20 : -if (!duplicate_rela (relas, i)) - (*gots)++; + (*gots)++;break ;default :break ;/* Do nothing. */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 425/457 ASoC: cs35l56: Update Firmware Addresses for CS35L63 for production silicon
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Binding <[email protected]>
[ Upstream commit f135fb24ef29335b94921077588cae445bc7f099 ]
Production silicon for CS36L63 has some small differences compared to pre-production silicon. Update firmware addresses, which are different.
No product was ever released with pre-production silicon so there is no need for the driver to include support for it.
--- include/sound/cs35l56.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/sound/cs35l56.h +2 -2
@@ -107,8 +107,8 @@#define CS35L56_DSP1_PMEM_5114 0x3804FE8#define CS35L63_DSP1_FW_VER CS35L56_DSP1_FW_VER -#define CS35L63_DSP1_HALO_STATE 0x280396C -#define CS35L63_DSP1_PM_CUR_STATE 0x28042C8 +#define CS35L63_DSP1_HALO_STATE 0x2803C04 +#define CS35L63_DSP1_PM_CUR_STATE 0x2804518#define CS35L63_PROTECTION_STATUS 0x340009C#define CS35L63_TRANSDUCER_ACTUAL_PS 0x34000F4#define CS35L63_MAIN_RENDER_USER_MUTE 0x3400020
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 426/457 ASoC: cs35l56: Handle new algorithms IDs for CS35L63
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit 8dadc11b67d4b83deff45e4889b3b5540b9c0a7f ]
CS35L63 uses different algorithm IDs from CS35L56.
Add a new mechanism to handle different alg IDs between parts in the CS35L56 driver.
--- include/sound/cs35l56.h | 1 + sound/soc/codecs/cs35l56-shared.c | 29 ++++++++++++++++++++++++++--- sound/soc/codecs/cs35l56.c | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-)
include/sound/cs35l56.h +1 -0
@@ -306,6 +306,7 @@ struct cs35l56_base {struct gpio_desc *reset_gpio;struct cs35l56_spi_payload *spi_payload_buf;const struct cs35l56_fw_reg *fw_reg; +const struct cirrus_amp_cal_controls *calibration_controls; };static inline bool cs35l56_is_otp_register (unsigned int reg)
sound/soc/codecs/cs35l56-shared.c +26 -3
@@ -838,6 +838,15 @@ const struct cirrus_amp_cal_controls cs35l56_calibration_controls = { };EXPORT_SYMBOL_NS_GPL (cs35l56_calibration_controls,"SND_SOC_CS35L56_SHARED" ); +static const struct cirrus_amp_cal_controls cs35l63_calibration_controls = { + .alg_id =0xbf210 , + .mem_region =WMFW_ADSP2_YM , + .ambient ="CAL_AMBIENT" , + .calr ="CAL_R" , + .status ="CAL_STATUS" , + .checksum ="CAL_CHECKSUM" , +}; +int cs35l56_get_calibration (struct cs35l56_base *cs35l56_base) {u64 silicon_uid =0 ;
@@ -912,19 +921,31 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, "SND_SOC_CS35L56_SHARED");void cs35l56_log_tuning (struct cs35l56_base *cs35l56_base,struct cs_dsp *cs_dsp) {__be32 pid, sid, tid; +unsigned int alg_id;int ret; +switch (cs35l56_base->type) { +case 0x54 : +case 0x56 : +case 0x57 : + alg_id =0x9f212 ; +break ; +default : + alg_id =0xbf212 ; +break ; + } + scoped_guard(mutex, &cs_dsp->pwr_lock) { ret =cs_dsp_coeff_read_ctrl (cs_dsp_get_ctl (cs_dsp,"AS_PRJCT_ID" , -WMFW_ADSP2_XM ,0x9f212 ), +WMFW_ADSP2_XM , alg_id),0 , &pid,sizeof (pid));if (!ret) ret =cs_dsp_coeff_read_ctrl (cs_dsp_get_ctl (cs_dsp,"AS_CHNNL_ID" , -WMFW_ADSP2_XM ,0x9f212 ), +WMFW_ADSP2_XM , alg_id),0 , &sid,sizeof (sid));if (!ret) ret =cs_dsp_coeff_read_ctrl (cs_dsp_get_ctl (cs_dsp,"AS_SNPSHT_ID" , -WMFW_ADSP2_XM ,0x9f212 ), +WMFW_ADSP2_XM , alg_id),0 , &tid,sizeof (tid)); }
@@ -974,8 +995,10 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)case 0x35A54 :case 0x35A56 :case 0x35A57 : + cs35l56_base->calibration_controls = &cs35l56_calibration_controls;break ;case 0x35A630 : + cs35l56_base->calibration_controls = &cs35l63_calibration_controls; devid = devid >>4 ;break ;default :
sound/soc/codecs/cs35l56.c +1 -1
@@ -695,7 +695,7 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56)return ret; ret =cs_amp_write_cal_coeffs (&cs35l56->dsp.cs_dsp, - &cs35l56_calibration_controls, + cs35l56->base.calibration_controls, &cs35l56->base.cal_data);wm_adsp_stop (&cs35l56->dsp);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 427/457 ASoC: cs35l56: Remove SoundWire Clock Divider workaround for CS35L63
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Binding <[email protected]>
[ Upstream commit 8d13d1bdb59d0a2c526869ee571ec51a3a887463 ]
Production silicon for CS36L63 has some small differences compared to pre-production silicon. Remove soundwire clock workaround as no longer necessary. We don't want to do tricks with low-level clocking controls if we don't need to.
--- sound/soc/codecs/cs35l56-sdw.c | 69 ---------------------------------- sound/soc/codecs/cs35l56.h | 3 -- 2 files changed, 72 deletions(-)
sound/soc/codecs/cs35l56-sdw.c +0 -69
@@ -394,74 +394,6 @@ static int cs35l56_sdw_update_status(struct sdw_slave *peripheral,return 0 ; } -static int cs35l63_sdw_kick_divider (struct cs35l56_private *cs35l56, -struct sdw_slave *peripheral) -{ -unsigned int curr_scale_reg, next_scale_reg; -int curr_scale, next_scale, ret; - -if (!cs35l56->base.init_done) -return 0 ; - -if (peripheral->bus->params.curr_bank) { - curr_scale_reg =SDW_SCP_BUSCLOCK_SCALE_B1 ; - next_scale_reg =SDW_SCP_BUSCLOCK_SCALE_B0 ; - }else { - curr_scale_reg =SDW_SCP_BUSCLOCK_SCALE_B0 ; - next_scale_reg =SDW_SCP_BUSCLOCK_SCALE_B1 ; - } - -/* -* Current clock scale value must be different to new value. -* Modify current to guarantee this. If next still has the dummy -* value we wrote when it was current, the core code has not set -* a new scale so restore its original good value -*/ - curr_scale =sdw_read_no_pm (peripheral, curr_scale_reg); -if (curr_scale <0 ) { -dev_err (cs35l56->base.dev,"Failed to read current clock scale: %d\n" , curr_scale); -return curr_scale; - } - - next_scale =sdw_read_no_pm (peripheral, next_scale_reg); -if (next_scale <0 ) { -dev_err (cs35l56->base.dev,"Failed to read next clock scale: %d\n" , next_scale); -return next_scale; - } - -if (next_scale ==CS35L56_SDW_INVALID_BUS_SCALE ) { - next_scale = cs35l56->old_sdw_clock_scale; - ret =sdw_write_no_pm (peripheral, next_scale_reg, next_scale); -if (ret <0 ) { -dev_err (cs35l56->base.dev,"Failed to modify current clock scale: %d\n" , - ret); -return ret; - } - } - - cs35l56->old_sdw_clock_scale = curr_scale; - ret =sdw_write_no_pm (peripheral, curr_scale_reg,CS35L56_SDW_INVALID_BUS_SCALE ); -if (ret <0 ) { -dev_err (cs35l56->base.dev,"Failed to modify current clock scale: %d\n" , ret); -return ret; - } - -dev_dbg (cs35l56->base.dev,"Next bus scale: %#x\n" , next_scale); - -return 0 ; -} - -static int cs35l56_sdw_bus_config (struct sdw_slave *peripheral, -struct sdw_bus_params *params) -{ -struct cs35l56_private *cs35l56 =dev_get_drvdata (&peripheral->dev); - -if ((cs35l56->base.type ==0x63 ) && (cs35l56->base.rev <0xa1 )) -return cs35l63_sdw_kick_divider (cs35l56, peripheral); - -return 0 ; -} -static int __maybe_unused cs35l56_sdw_clk_stop (struct sdw_slave *peripheral,enum sdw_clk_stop_mode mode,enum sdw_clk_stop_type type)
@@ -477,7 +409,6 @@ static const struct sdw_slave_ops cs35l56_sdw_ops = { .read_prop = cs35l56_sdw_read_prop, .interrupt_callback = cs35l56_sdw_interrupt, .update_status = cs35l56_sdw_update_status, - .bus_config = cs35l56_sdw_bus_config,#ifdef DEBUG .clk_stop = cs35l56_sdw_clk_stop,#endif
sound/soc/codecs/cs35l56.h +0 -3
@@ -20,8 +20,6 @@#define CS35L56_SDW_GEN_INT_MASK_1 0xc1#define CS35L56_SDW_INT_MASK_CODEC_IRQ BIT(0) -#define CS35L56_SDW_INVALID_BUS_SCALE 0xf -#define CS35L56_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)#define CS35L56_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE \ | SNDRV_PCM_FMTBIT_S32_LE)
@@ -52,7 +50,6 @@ struct cs35l56_private {u8 asp_slot_count;bool tdm_mode;bool sysclk_set; -u8 old_sdw_clock_scale;u8 sdw_link_num;u8 sdw_unique_id; };
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 428/457 s390/mm: Do not map lowcore with identity mapping
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
[ Upstream commit 93f616ff870a1fb7e84d472cad0af651b18f9f87 ]
Since the identity mapping is pinned to address zero the lowcore is always also mapped to address zero, this happens regardless of the relocate_lowcore command line option. If the option is specified the lowcore is mapped twice, instead of only once.
This means that NULL pointer accesses will succeed instead of causing an exception (low address protection still applies, but covers only parts). To fix this never map the first two pages of physical memory with the identity mapping.
--- arch/s390/boot/vmem.c | 3 +++ 1 file changed, 3 insertions(+)
arch/s390/boot/vmem.c +3 -0
@@ -530,6 +530,9 @@ void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned l lowcore_address +sizeof (struct lowcore ), POPULATE_LOWCORE);for_each_physmem_usable_range (i, &start, &end) { +/* Do not map lowcore with identity mapping */ +if (!start) + start =sizeof (struct lowcore );pgtable_populate ((unsigned long )__identity_va (start), (unsigned long )__identity_va (end),POPULATE_IDENTITY );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 429/457 LoongArch: KVM: Use standard bitops API with eiointc
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao <[email protected]>
[ Upstream commit d23bd878f6ea9cff93104159356e012a8b2bbfaf ]
Standard bitops APIs such test_bit() is used here, rather than manually calculating the offset and mask. Also use non-atomic API __set_bit() and __clear_bit() rather than set_bit() and clear_bit(), since the global spinlock is held already.
Stable-dep-of: 0dfd9ea7bf80 ("LoongArch: KVM: Use kvm_get_vcpu_by_id() instead of kvm_get_vcpu()")
--- arch/loongarch/kvm/intc/eiointc.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-)
arch/loongarch/kvm/intc/eiointc.c +11 -16
@@ -9,7 +9,7 @@static void eiointc_set_sw_coreisr (struct loongarch_eiointc *s) { -int ipnum, cpu, cpuid, irq_index, irq_mask, irq; +int ipnum, cpu, cpuid, irq;struct kvm_vcpu *vcpu;for (irq =0 ; irq <EIOINTC_IRQS ; irq++) {
@@ -18,8 +18,6 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s) ipnum =count_trailing_zeros (ipnum); ipnum = (ipnum >=0 && ipnum <4 ) ? ipnum :0 ; } - irq_index = irq /32 ; - irq_mask =BIT (irq &0x1f ); cpuid = s->coremap.reg_u8[irq]; vcpu =kvm_get_vcpu_by_cpuid (s->kvm, cpuid);
@@ -27,16 +25,16 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)continue ; cpu = vcpu->vcpu_id; -if (!!(s->coreisr.reg_u32[cpu][irq_index] & irq_mask)) -set_bit (irq, s->sw_coreisr[cpu][ipnum]); +if (test_bit (irq, (unsigned long *)s->coreisr.reg_u32[cpu])) +__set_bit (irq, s->sw_coreisr[cpu][ipnum]);else -clear_bit (irq, s->sw_coreisr[cpu][ipnum]); +__clear_bit (irq, s->sw_coreisr[cpu][ipnum]); } }static void eiointc_update_irq (struct loongarch_eiointc *s,int irq,int level) { -int ipnum, cpu, found, irq_index, irq_mask; +int ipnum, cpu, found;struct kvm_vcpu *vcpu;struct kvm_interrupt vcpu_irq;
@@ -48,19 +46,16 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level) cpu = s->sw_coremap[irq]; vcpu =kvm_get_vcpu (s->kvm, cpu); - irq_index = irq /32 ; - irq_mask =BIT (irq &0x1f ); -if (level) {/* if not enable return false */ -if (((s->enable.reg_u32[irq_index]) & irq_mask) ==0 ) +if (!test_bit (irq, (unsigned long *)s->enable.reg_u32))return ; - s->coreisr.reg_u32[cpu][irq_index] |= irq_mask; +__set_bit (irq, (unsigned long *)s->coreisr.reg_u32[cpu]); found =find_first_bit (s->sw_coreisr[cpu][ipnum],EIOINTC_IRQS ); -set_bit (irq, s->sw_coreisr[cpu][ipnum]); +__set_bit (irq, s->sw_coreisr[cpu][ipnum]); }else { - s->coreisr.reg_u32[cpu][irq_index] &= ~irq_mask; -clear_bit (irq, s->sw_coreisr[cpu][ipnum]); +__clear_bit (irq, (unsigned long *)s->coreisr.reg_u32[cpu]); +__clear_bit (irq, s->sw_coreisr[cpu][ipnum]); found =find_first_bit (s->sw_coreisr[cpu][ipnum],EIOINTC_IRQS ); }
@@ -110,8 +105,8 @@ void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level)unsigned long flags;unsigned long *isr = (unsigned long *)s->isr.reg_u8; - level ?set_bit (irq, isr) :clear_bit (irq, isr);spin_lock_irqsave (&s->lock, flags); + level ?__set_bit (irq, isr) :__clear_bit (irq, isr);eiointc_update_irq (s, irq, level);spin_unlock_irqrestore (&s->lock, flags); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 430/457 LoongArch: KVM: Use kvm_get_vcpu_by_id() instead of kvm_get_vcpu()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Gao <[email protected]>
[ Upstream commit 0dfd9ea7bf80fabe11f5b775d762a5cd168cdf41 ]
Since using kvm_get_vcpu() may fail to retrieve the vCPU context, kvm_get_vcpu_by_id() should be used instead.
--- arch/loongarch/kvm/intc/eiointc.c | 7 ++++++- arch/loongarch/kvm/intc/ipi.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-)
arch/loongarch/kvm/intc/eiointc.c +6 -1
@@ -45,7 +45,12 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level) } cpu = s->sw_coremap[irq]; - vcpu =kvm_get_vcpu (s->kvm, cpu); + vcpu =kvm_get_vcpu_by_id (s->kvm, cpu); +if (unlikely (vcpu ==NULL )) { +kvm_err ("%s: invalid target cpu: %d\n" , __func__, cpu); +return ; + } +if (level) {/* if not enable return false */ if (!test_bit (irq, (unsigned long *)s->enable.reg_u32))
arch/loongarch/kvm/intc/ipi.c +1 -1
@@ -318,7 +318,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev, cpu = (attr->attr >>16 ) &0x3ff ; addr = attr->attr &0xff ; - vcpu =kvm_get_vcpu (dev->kvm, cpu); + vcpu =kvm_get_vcpu_by_id (dev->kvm, cpu);if (unlikely (vcpu ==NULL )) {kvm_err ("%s: invalid target cpu: %d\n" , __func__, cpu);return -EINVAL ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 431/457 ixgbe: xsk: resolve the negative overflow of budget in ixgbe_xmit_zc
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Xing <[email protected]>
[ Upstream commit 4d4d9ef9dfee877d494e5418f68a1016ef08cad6 ]
Resolve the budget negative overflow which leads to returning true in ixgbe_xmit_zc even when the budget of descs are thoroughly consumed.
Before this patch, when the budget is decreased to zero and finishes sending the last allowed desc in ixgbe_xmit_zc, it will always turn back and enter into the while() statement to see if it should keep processing packets, but in the meantime it unexpectedly decreases the value again to 'unsigned int (0--)', namely, UINT_MAX. Finally, the ixgbe_xmit_zc returns true, showing 'we complete cleaning the budget'. That also means 'clean_complete = true' in ixgbe_poll.
The true theory behind this is if that budget number of descs are consumed, it implies that we might have more descs to be done. So we should return false in ixgbe_xmit_zc to tell napi poll to find another chance to start polling to handle the rest of descs. On the contrary, returning true here means job done and we know we finish all the possible descs this time and we don't intend to start a new napi poll.
It is apparently against our expectations. Please also see how ixgbe_clean_tx_irq() handles the problem: it uses do..while() statement to make sure the budget can be decreased to zero at most and the negative overflow never happens.
The patch adds 'likely' because we rarely would not hit the loop condition since the standard budget is 256.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +3 -1
@@ -398,7 +398,7 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget)dma_addr_t dma;u32 cmd_type; -while (budget-- >0 ) { +while (likely (budget)) {if (unlikely (!ixgbe_desc_unused (xdp_ring))) { work_done = false;break ;
@@ -433,6 +433,8 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget) xdp_ring->next_to_use++;if (xdp_ring->next_to_use == xdp_ring->count) xdp_ring->next_to_use =0 ; + + budget--; }if (tx_desc) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 432/457 igc: fix disabling L1.2 PCI-E link substate on I226 on init
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: ValdikSS <[email protected]>
[ Upstream commit 1468c1f97cf32418e34dbb40b784ed9333b9e123 ]
Device ID comparison in igc_is_device_id_i226 is performed before the ID is set, resulting in always failing check on init.
Before the patch:
* L1.2 is not disabled on init
* L1.2 is properly disabled after suspend-resume cycle
With the patch:
* L1.2 is properly disabled both on init and after suspend-resume
How to test:
Connect to the 1G link with 300+ mbit/s Internet speed, and run the download speed test, such as:
curl -o /dev/null http://speedtest.selectel.ru/1GB
Without L1.2 disabled, the speed would be no more than ~200 mbit/s. With L1.2 disabled, the speed would reach 1 gbit/s.
Note: it's required that the latency between your host and the remote be around 3-5 ms, the test inside LAN (<1 ms latency) won't trigger the issue.
--- drivers/net/ethernet/intel/igc/igc_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/net/ethernet/intel/igc/igc_main.c +7 -7
@@ -7115,6 +7115,13 @@ static int igc_probe(struct pci_dev *pdev, adapter->port_num = hw->bus.func; adapter->msg_enable =netif_msg_init (debug,DEFAULT_MSG_ENABLE ); +/* PCI config space info */ + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->revision_id = pdev->revision; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_device_id = pdev->subsystem_device; +/* Disable ASPM L1.2 on I226 devices to avoid packet loss */ if (igc_is_device_id_i226 (hw))pci_disable_link_state (pdev,PCIE_LINK_STATE_L1_2 );
@@ -7141,13 +7148,6 @@ static int igc_probe(struct pci_dev *pdev, netdev->mem_start =pci_resource_start (pdev,0 ); netdev->mem_end =pci_resource_end (pdev,0 ); -/* PCI config space info */ - hw->vendor_id = pdev->vendor; - hw->device_id = pdev->device; - hw->revision_id = pdev->revision; - hw->subsystem_vendor_id = pdev->subsystem_vendor; - hw->subsystem_device_id = pdev->subsystem_device; -/* Copy the default MAC and PHY function pointers */ memcpy (&hw->mac.ops, ei->mac_ops,sizeof (hw->mac.ops));memcpy (&hw->phy.ops, ei->phy_ops,sizeof (hw->phy.ops));
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 433/457 net: dsa: microchip: Fix KSZ9477 HSR port setup issue
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristram Ha <[email protected]>
[ Upstream commit e318cd6714592fb762fcab59c5684a442243a12f ]
ksz9477_hsr_join() is called once to setup the HSR port membership, but the port can be enabled later, or disabled and enabled back and the port membership is not set correctly inside ksz_update_port_member(). The added code always use the correct HSR port membership for HSR port that is enabled.
--- drivers/net/dsa/microchip/ksz_common.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/dsa/microchip/ksz_common.c +6 -0
@@ -2347,6 +2347,12 @@ static void ksz_update_port_member(struct ksz_device *dev, int port) dev->dev_ops->cfg_port_member (dev, i, val | cpu_port); } +/* HSR ports are setup once so need to use the assigned membership +* when the port is enabled. +*/ +if (!port_member && p->stp_state ==BR_STATE_FORWARDING && + (dev->hsr_ports &BIT (port))) + port_member = dev->hsr_ports; dev->dev_ops->cfg_port_member (dev, port, port_member | cpu_port); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 434/457 net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Liu <[email protected]>
[ Upstream commit 15de71d06a400f7fdc15bf377a2552b0ec437cf5 ]
The following setup can trigger a WARNING in htb_activate due to the condition: !cl->leaf.q->q.qlen
tc qdisc del dev lo root
tc qdisc add dev lo root handle 1: htb default 1
tc class add dev lo parent 1: classid 1:1 \
htb rate 64bit
tc qdisc add dev lo parent 1:1 handle f: \
cake memlimit 1b
ping -I lo -f -c1 -s64 -W0.001 127.0.0.1
This is because the low memlimit leads to a low buffer_limit, which causes packet dropping. However, cake_enqueue still returns NET_XMIT_SUCCESS, causing htb_enqueue to call htb_activate with an empty child qdisc. We should return NET_XMIT_CN when packets are dropped from the same tin and flow.
I do not believe return value of NET_XMIT_CN is necessary for packet drops in the case of ack filtering, as that is meant to optimize performance, not to signal congestion.
--- net/sched/sch_cake.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
net/sched/sch_cake.c +12 -2
@@ -1747,7 +1747,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,ktime_t now =ktime_get ();struct cake_tin_data *b;struct cake_flow *flow; -u32 idx; +u32 idx, tin;/* choose flow to insert into */ idx =cake_classify (sch, &b, skb, q->flow_mode, &ret);
@@ -1757,6 +1757,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,__qdisc_drop (skb, to_free);return ret; } + tin = (u32)(b - q->tins); idx--; flow = &b->flows[idx];
@@ -1924,13 +1925,22 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, q->buffer_max_used = q->buffer_used;if (q->buffer_used > q->buffer_limit) { +bool same_flow = false;u32 dropped =0 ; +u32 drop_id;while (q->buffer_used > q->buffer_limit) { dropped++; -cake_drop (sch, to_free); + drop_id =cake_drop (sch, to_free); + +if ((drop_id >>16 ) == tin && + (drop_id &0xFFFF ) == idx) + same_flow = true; } b->drop_overlimit += dropped; + +if (same_flow) +return NET_XMIT_CN ; }return NET_XMIT_SUCCESS ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 435/457 net/sched: Remove unnecessary WARNING condition for empty child qdisc in htb_activate
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Liu <[email protected]>
[ Upstream commit 2c2192e5f9c7c2892fe2363244d1387f62710d83 ]
The WARN_ON trigger based on !cl->leaf.q->q.qlen is unnecessary in htb_activate. htb_dequeue_tree already accounts for that scenario.
--- net/sched/sch_htb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/sch_htb.c +1 -1
@@ -592,7 +592,7 @@ htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, s64 *diff)*/ static inline void htb_activate (struct htb_sched *q,struct htb_class *cl) { -WARN_ON (cl->level || !cl->leaf.q || !cl->leaf.q->q.qlen); +WARN_ON (cl->level || !cl->leaf.q);if (!cl->prio_activity) { cl->prio_activity =1 << cl->prio;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 436/457 ALSA: timer: fix ida_free call while not allocated
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dewei Meng <[email protected]>
[ Upstream commit 5003a65790ed66be882d1987cc2ca86af0de3db1 ]
In the snd_utimer_create() function, if the kasprintf() function return NULL, snd_utimer_put_id() will be called, finally use ida_free() to free the unallocated id 0.
the syzkaller reported the following information:
------------[ cut here ]------------ ida_free called for id=0 which is not allocated. WARNING: CPU: 1 PID: 1286 at lib/idr.c:592 ida_free+0x1fd/0x2f0 lib/idr.c:592 Modules linked in: CPU: 1 UID: 0 PID: 1286 Comm: syz-executor164 Not tainted 6.15.8 #3 PREEMPT(lazy) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.fc42 04/01/2014 RIP: 0010:ida_free+0x1fd/0x2f0 lib/idr.c:592 Code: f8 fc 41 83 fc 3e 76 69 e8 70 b2 f8 (...) RSP: 0018:ffffc900007f79c8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 1ffff920000fef3b RCX: ffffffff872176a5 RDX: ffff88800369d200 RSI: 0000000000000000 RDI: ffff88800369d200 RBP: 0000000000000000 R08: ffffffff87ba60a5 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000002 R14: 0000000000000000 R15: 0000000000000000 FS: 00007f6f1abc1740(0000) GS:ffff8880d76a0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f6f1ad7a784 CR3: 000000007a6e2000 CR4: 00000000000006f0 Call Trace: <TASK> snd_utimer_put_id sound/core/timer.c:2043 [inline] [snd_timer] snd_utimer_create+0x59b/0x6a0 sound/core/timer.c:2184 [snd_timer] snd_utimer_ioctl_create sound/core/timer.c:2202 [inline] [snd_timer] __snd_timer_user_ioctl.isra.0+0x724/0x1340 sound/core/timer.c:2287 [snd_timer] snd_timer_user_ioctl+0x75/0xc0 sound/core/timer.c:2298 [snd_timer] vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x198/0x200 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x7b/0x160 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e [...]
The utimer->id should be set properly before the kasprintf() function, ensures the snd_utimer_put_id() function will free the allocated id.
--- sound/core/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/core/timer.c +2 -2
@@ -2139,14 +2139,14 @@ static int snd_utimer_create(struct snd_timer_uinfo *utimer_info, goto err_take_id; } + utimer->id = utimer_id; + utimer->name =kasprintf (GFP_KERNEL ,"snd-utimer%d" , utimer_id);if (!utimer->name) { err = -ENOMEM ; goto err_get_name; } - utimer->id = utimer_id; - tid.dev_sclass =SNDRV_TIMER_SCLASS_APPLICATION ; tid.dev_class =SNDRV_TIMER_CLASS_GLOBAL ; tid.card =-1 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 437/457 bonding: update LACP activity flag after setting lacp_active
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit b64d035f77b1f02ab449393342264b44950a75ae ]
The port's actor_oper_port_state activity flag should be updated immediately after changing the lacp_active option to reflect the current mode correctly.
--- drivers/net/bonding/bond_3ad.c | 25 +++++++++++++++++++++++++ drivers/net/bonding/bond_options.c | 1 + include/net/bond_3ad.h | 1 + 3 files changed, 27 insertions(+)
drivers/net/bonding/bond_3ad.c +25 -0
@@ -2869,6 +2869,31 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)spin_unlock_bh (&bond->mode_lock); } +/** +* bond_3ad_update_lacp_active - change the lacp active +* @bond: bonding struct +* +* Update actor_oper_port_state when lacp_active is modified. +*/ +void bond_3ad_update_lacp_active (struct bonding *bond) +{ +struct port *port =NULL ; +struct list_head *iter; +struct slave *slave; +int lacp_active; + + lacp_active = bond->params.lacp_active; +spin_lock_bh (&bond->mode_lock); +bond_for_each_slave (bond, slave, iter) { + port = &(SLAVE_AD_INFO (slave)->port); +if (lacp_active) + port->actor_oper_port_state |=LACP_STATE_LACP_ACTIVITY ; +else + port->actor_oper_port_state &= ~LACP_STATE_LACP_ACTIVITY ; + } +spin_unlock_bh (&bond->mode_lock); +} +size_t bond_3ad_stats_size (void ) { return nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_RX */
drivers/net/bonding/bond_options.c +1 -0
@@ -1637,6 +1637,7 @@ static int bond_option_lacp_active_set(struct bonding *bond,netdev_dbg (bond->dev,"Setting LACP active to %s (%llu)\n" , newval->string, newval->value); bond->params.lacp_active = newval->value; +bond_3ad_update_lacp_active (bond);return 0 ; }
include/net/bond_3ad.h +1 -0
@@ -307,6 +307,7 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);int bond_3ad_set_carrier (struct bonding *bond);void bond_3ad_update_lacp_rate (struct bonding *bond); +void bond_3ad_update_lacp_active (struct bonding *bond);void bond_3ad_update_ad_actor_settings (struct bonding *bond);int bond_3ad_stats_fill (struct sk_buff *skb,struct bond_3ad_stats *stats);size_t bond_3ad_stats_size (void );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 438/457 bonding: send LACPDUs periodically in passive mode after receiving partners LACPDU
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 0599640a21e98f0d6a3e9ff85c0a687c90a8103b ]
When lacp_active is set to off, the bond operates in passive mode, meaning it only "speaks when spoken to." However, the current kernel implementation only sends an LACPDU in response when the partner's state changes.
As a result, once LACP negotiation succeeds, the actor stops sending LACPDUs until the partner times out and sends an "expired" LACPDU. This causes continuous LACP state flapping.
According to IEEE 802.1AX-2014, 6.4.13 Periodic Transmission machine. The values of Partner_Oper_Port_State.LACP_Activity and Actor_Oper_Port_State.LACP_Activity determine whether periodic transmissions take place. If either or both parameters are set to Active LACP, then periodic transmissions occur; if both are set to Passive LACP, then periodic transmissions do not occur.
To comply with this, we remove the !bond->params.lacp_active check in ad_periodic_machine(). Instead, we initialize the actor's port's LACP_STATE_LACP_ACTIVITY state based on lacp_active setting.
Additionally, we avoid setting the partner's state to LACP_STATE_LACP_ACTIVITY in the EXPIRED state, since we should not assume the partner is active by default.
This ensures that in passive mode, the bond starts sending periodic LACPDUs after receiving one from the partner, and avoids flapping due to inactivity.
--- drivers/net/bonding/bond_3ad.c | 42 +++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-)
drivers/net/bonding/bond_3ad.c +24 -18
@@ -95,13 +95,13 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker);static void ad_mux_machine (struct port *port,bool *update_slave_arr);static void ad_rx_machine (struct lacpdu *lacpdu,struct port *port);static void ad_tx_machine (struct port *port); -static void ad_periodic_machine (struct port *port,struct bond_params *bond_params); +static void ad_periodic_machine (struct port *port);static void ad_port_selection_logic (struct port *port,bool *update_slave_arr);static void ad_agg_selection_logic (struct aggregator *aggregator,bool *update_slave_arr);static void ad_clear_agg (struct aggregator *aggregator);static void ad_initialize_agg (struct aggregator *aggregator); -static void ad_initialize_port (struct port *port,int lacp_fast); +static void ad_initialize_port (struct port *port,const struct bond_params *bond_params);static void ad_enable_collecting (struct port *port);static void ad_disable_distributing (struct port *port,bool *update_slave_arr);
@@ -1296,10 +1296,16 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)* case of EXPIRED even if LINK_DOWN didn't arrive for * the port. */ - port->partner_oper.port_state &= ~LACP_STATE_SYNCHRONIZATION ; port->sm_vars &= ~AD_PORT_MATCHED ; +/* Based on IEEE 8021AX-2014, Figure 6-18 - Receive +* machine state diagram, the statue should be +* Partner_Oper_Port_State.Synchronization = FALSE; +* Partner_Oper_Port_State.LACP_Timeout = Short Timeout; +* start current_while_timer(Short Timeout); +* Actor_Oper_Port_State.Expired = TRUE; +*/ + port->partner_oper.port_state &= ~LACP_STATE_SYNCHRONIZATION ; port->partner_oper.port_state |=LACP_STATE_LACP_TIMEOUT ; - port->partner_oper.port_state |=LACP_STATE_LACP_ACTIVITY ; port->sm_rx_timer_counter =__ad_timer_to_ticks (AD_CURRENT_WHILE_TIMER , (u16)(AD_SHORT_TIMEOUT )); port->actor_oper_port_state |=LACP_STATE_EXPIRED ; port->sm_vars |=AD_PORT_CHURNED ;
@@ -1405,11 +1411,10 @@ static void ad_tx_machine(struct port *port)/** * ad_periodic_machine - handle a port's periodic state machine * @port: the port we're looking at -* @bond_params: bond parameters we will use * * Turn ntt flag on priodically to perform periodic transmission of lacpdu's. */ -static void ad_periodic_machine (struct port *port,struct bond_params *bond_params) +static void ad_periodic_machine (struct port *port) {periodic_states_t last_state;
@@ -1418,8 +1423,7 @@ static void ad_periodic_machine(struct port *port, struct bond_params *bond_para/* check if port was reinitialized */ if (((port->sm_vars &AD_PORT_BEGIN ) || !(port->sm_vars &AD_PORT_LACP_ENABLED ) || !port->is_enabled) || - (!(port->actor_oper_port_state &LACP_STATE_LACP_ACTIVITY ) && !(port->partner_oper.port_state &LACP_STATE_LACP_ACTIVITY )) || - !bond_params->lacp_active) { + (!(port->actor_oper_port_state &LACP_STATE_LACP_ACTIVITY ) && !(port->partner_oper.port_state &LACP_STATE_LACP_ACTIVITY ))) { port->sm_periodic_state =AD_NO_PERIODIC ; }/* check if state machine should change state */
@@ -1943,16 +1947,16 @@ static void ad_initialize_agg(struct aggregator *aggregator)/** * ad_initialize_port - initialize a given port's parameters * @port: the port we're looking at -* @lacp_fast: boolean. whether fast periodic should be used +* @bond_params: bond parameters we will use */ -static void ad_initialize_port (struct port *port,int lacp_fast) +static void ad_initialize_port (struct port *port,const struct bond_params *bond_params) {static const struct port_params tmpl = { .system_priority =0xffff , .key =1 , .port_number =1 , .port_priority =0xff , - .port_state =1 , + .port_state =0 , };static const struct lacpdu lacpdu = { .subtype =0x01 ,
@@ -1970,12 +1974,14 @@ static void ad_initialize_port(struct port *port, int lacp_fast) port->actor_port_priority =0xff ; port->actor_port_aggregator_identifier =0 ; port->ntt = false; - port->actor_admin_port_state =LACP_STATE_AGGREGATION | -LACP_STATE_LACP_ACTIVITY ; - port->actor_oper_port_state =LACP_STATE_AGGREGATION | -LACP_STATE_LACP_ACTIVITY ; + port->actor_admin_port_state =LACP_STATE_AGGREGATION ; + port->actor_oper_port_state =LACP_STATE_AGGREGATION ; +if (bond_params->lacp_active) { + port->actor_admin_port_state |=LACP_STATE_LACP_ACTIVITY ; + port->actor_oper_port_state |=LACP_STATE_LACP_ACTIVITY ; + } -if (lacp_fast) +if (bond_params->lacp_fast) port->actor_oper_port_state |=LACP_STATE_LACP_TIMEOUT ;memcpy (&port->partner_admin, &tmpl,sizeof (tmpl));
@@ -2187,7 +2193,7 @@ void bond_3ad_bind_slave(struct slave *slave)/* port initialization */ port = &(SLAVE_AD_INFO (slave)->port); -ad_initialize_port (port, bond->params.lacp_fast); +ad_initialize_port (port, &bond->params); port->slave = slave; port->actor_port_number =SLAVE_AD_INFO (slave)->id;
@@ -2499,7 +2505,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) }ad_rx_machine (NULL , port); -ad_periodic_machine (port, &bond->params); +ad_periodic_machine (port);ad_port_selection_logic (port, &update_slave_arr);ad_mux_machine (port, &update_slave_arr);ad_tx_machine (port);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 439/457 net: airoha: ppe: Do not invalid PPE entries in case of SW hash collision
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 9f6b606b6b37e61427412708411e8e04b1a858e8 ]
SW hash computed by airoha_ppe_foe_get_entry_hash routine (used for foe_flow hlist) can theoretically produce collisions between two different HW PPE entries.
In airoha_ppe_foe_insert_entry() if the collision occurs we will mark the second PPE entry in the list as stale (setting the hw hash to 0xffff). Stale entries are no more updated in airoha_ppe_foe_flow_entry_update routine and so they are removed by Netfilter.
Fix the problem not marking the second entry as stale in airoha_ppe_foe_insert_entry routine if we have already inserted the brand new entry in the PPE table and let Netfilter remove real stale entries according to their timestamp.
Please note this is just a theoretical issue spotted reviewing the code and not faced running the system.
--- drivers/net/ethernet/airoha/airoha_ppe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/airoha/airoha_ppe.c +1 -3
@@ -726,10 +726,8 @@ static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe,continue ; } -if (commit_done || !airoha_ppe_foe_compare_entry (e, hwe)) { - e->hash =0xffff ; +if (!airoha_ppe_foe_compare_entry (e, hwe))continue ; - }airoha_ppe_foe_commit_entry (ppe, &e->data, hash); commit_done = true;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 440/457 block: move elevator queue allocation logic into blk_mq_init_sched
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit 49811586be373e26a3ab52f54e0dfa663c02fddd ]
In preparation for allocating sched_tags before freezing the request queue and acquiring ->elevator_lock, move the elevator queue allocation logic from the elevator ops ->init_sched callback into blk_mq_init_sched. As elevator_alloc is now only invoked from block layer core, we don't need to export it, so unexport elevator_alloc function.
This refactoring provides a centralized location for elevator queue initialization, which makes it easier to store pre-allocated sched_tags in the struct elevator_queue during later changes.
Stable-dep-of: 2d82f3bd8910 ("blk-mq: fix lockdep warning in __blk_mq_update_nr_hw_queues")
--- block/bfq-iosched.c | 13 +++---------- block/blk-mq-sched.c | 11 ++++++++--- block/elevator.c | 1 - block/elevator.h | 2 +- block/kyber-iosched.c | 11 ++--------- block/mq-deadline.c | 14 ++------------ 6 files changed, 16 insertions(+), 36 deletions(-)
block/bfq-iosched.c +3 -10
@@ -7229,22 +7229,16 @@ static void bfq_init_root_group(struct bfq_group *root_group, root_group->sched_data.bfq_class_idle_last_service = jiffies; } -static int bfq_init_queue (struct request_queue *q,struct elevator_type *e) +static int bfq_init_queue (struct request_queue *q,struct elevator_queue *eq) {struct bfq_data *bfqd; -struct elevator_queue *eq;unsigned int i;struct blk_independent_access_ranges *ia_ranges = q->disk->ia_ranges; - eq =elevator_alloc (q, e); -if (!eq) -return -ENOMEM ; - bfqd =kzalloc_node (sizeof (*bfqd),GFP_KERNEL , q->node); -if (!bfqd) { -kobject_put (&eq->kobj); +if (!bfqd)return -ENOMEM ; - } + eq->elevator_data = bfqd;spin_lock_irq (&q->queue_lock);
@@ -7402,7 +7396,6 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) out_free:kfree (bfqd); -kobject_put (&eq->kobj);return -ENOMEM ; }
block/blk-mq-sched.c +8 -3
@@ -475,10 +475,14 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) q->nr_requests = 2 * min_t(unsigned int, q->tag_set->queue_depth,BLKDEV_DEFAULT_RQ ); + eq =elevator_alloc (q, e); +if (!eq) +return -ENOMEM ; +if (blk_mq_is_shared_tags (flags)) { ret =blk_mq_init_sched_shared_tags (q);if (ret) -return ret; + goto err_put_elevator; }queue_for_each_hw_ctx (q, hctx, i) {
@@ -487,7 +491,7 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) goto err_free_map_and_rqs; } - ret = e->ops.init_sched (q, e); + ret = e->ops.init_sched (q, eq);if (ret) goto err_free_map_and_rqs;
@@ -508,7 +512,8 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) err_free_map_and_rqs:blk_mq_sched_free_rqs (q);blk_mq_sched_tags_teardown (q, flags); - +err_put_elevator: +kobject_put (&eq->kobj); q->elevator =NULL ;return ret; }
block/elevator.c +0 -1
@@ -148,7 +148,6 @@ struct elevator_queue *elevator_alloc(struct request_queue *q,return eq; } -EXPORT_SYMBOL (elevator_alloc);static void elevator_release (struct kobject *kobj) {
block/elevator.h +1 -1
@@ -24,7 +24,7 @@ struct blk_mq_alloc_data;struct blk_mq_hw_ctx ;struct elevator_mq_ops { -int (*init_sched)(struct request_queue *,struct elevator_type *); +int (*init_sched)(struct request_queue *,struct elevator_queue *);void (*exit_sched)(struct elevator_queue *);int (*init_hctx)(struct blk_mq_hw_ctx *,unsigned int );void (*exit_hctx)(struct blk_mq_hw_ctx *,unsigned int );
block/kyber-iosched.c +2 -9
@@ -399,20 +399,13 @@ static struct kyber_queue_data *kyber_queue_data_alloc(struct request_queue *q)return ERR_PTR (ret); } -static int kyber_init_sched (struct request_queue *q,struct elevator_type *e) +static int kyber_init_sched (struct request_queue *q,struct elevator_queue *eq) {struct kyber_queue_data *kqd; -struct elevator_queue *eq; - - eq =elevator_alloc (q, e); -if (!eq) -return -ENOMEM ; kqd =kyber_queue_data_alloc (q); -if (IS_ERR (kqd)) { -kobject_put (&eq->kobj); +if (IS_ERR (kqd))return PTR_ERR (kqd); - }blk_stat_enable_accounting (q);
block/mq-deadline.c +2 -12
@@ -554,20 +554,14 @@ static void dd_exit_sched(struct elevator_queue *e)/* * initialize elevator private data (deadline_data). */ -static int dd_init_sched (struct request_queue *q,struct elevator_type *e) +static int dd_init_sched (struct request_queue *q,struct elevator_queue *eq) {struct deadline_data *dd; -struct elevator_queue *eq;enum dd_prio prio; -int ret = -ENOMEM ; - - eq =elevator_alloc (q, e); -if (!eq) -return ret; dd =kzalloc_node (sizeof (*dd),GFP_KERNEL , q->node);if (!dd) - goto put_eq; +return -ENOMEM ; eq->elevator_data = dd;
@@ -594,10 +588,6 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e) q->elevator = eq;return 0 ; - -put_eq: -kobject_put (&eq->kobj); -return ret; }/*
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 441/457 block: fix lockdep warning caused by lock dependency in elv_iosched_store
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit f5a6604f7a4405450e4a1f54e5430f47290c500f ]
Recent lockdep reports [1] have revealed a potential deadlock caused by a lock dependency between the percpu allocator lock and the elevator lock. This issue can be avoided by ensuring that the allocation and release of scheduler tags (sched_tags) are performed outside the elevator lock. Furthermore, the queue does not need to be remain frozen during these operations.
To address this, move all sched_tags allocations and deallocations outside of both the ->elevator_lock and the ->freeze_lock. Since the lifetime of the elevator queue and its associated sched_tags is closely tied, the allocated sched_tags are now stored in the elevator queue structure. Then, during the actual elevator switch (which runs under ->freeze_lock and ->elevator_lock), the pre-allocated sched_tags are assigned to the appropriate q->hctx. Once the elevator switch is complete and the locks are released, the old elevator queue and its associated sched_tags are freed.
This commit specifically addresses the allocation/deallocation of sched_ tags during elevator switching. Note that sched_tags may also be allocated in other contexts, such as during nr_hw_queues updates. Supporting that use case will require batch allocation/deallocation, which will be handled in a follow-up patch.
This restructuring ensures that sched_tags memory management occurs entirely outside of the ->elevator_lock and ->freeze_lock context, eliminating the lock dependency problem seen during scheduler updates.
[1] https://lore.kernel.org/all/[email protected]/
Stable-dep-of: 2d82f3bd8910 ("blk-mq: fix lockdep warning in __blk_mq_update_nr_hw_queues")
--- block/blk-mq-sched.c | 155 +++++++++++++++++++++++-------------------- block/blk-mq-sched.h | 8 ++- block/elevator.c | 40 +++++++++-- block/elevator.h | 14 +++- 4 files changed, 136 insertions(+), 81 deletions(-)
block/blk-mq-sched.c +83 -72
@@ -374,64 +374,17 @@ bool blk_mq_sched_try_insert_merge(struct request_queue *q, struct request *rq, }EXPORT_SYMBOL_GPL (blk_mq_sched_try_insert_merge); -static int blk_mq_sched_alloc_map_and_rqs (struct request_queue *q, -struct blk_mq_hw_ctx *hctx, -unsigned int hctx_idx) -{ -if (blk_mq_is_shared_tags (q->tag_set->flags)) { - hctx->sched_tags = q->sched_shared_tags; -return 0 ; - } - - hctx->sched_tags =blk_mq_alloc_map_and_rqs (q->tag_set, hctx_idx, - q->nr_requests); - -if (!hctx->sched_tags) -return -ENOMEM ; -return 0 ; -} - -static void blk_mq_exit_sched_shared_tags (struct request_queue *queue) -{ -blk_mq_free_rq_map (queue->sched_shared_tags); - queue->sched_shared_tags =NULL ; -} -/* called in queue's release handler, tagset has gone away */ static void blk_mq_sched_tags_teardown (struct request_queue *q,unsigned int flags) {struct blk_mq_hw_ctx *hctx;unsigned long i; -queue_for_each_hw_ctx (q, hctx, i) { -if (hctx->sched_tags) { -if (!blk_mq_is_shared_tags (flags)) -blk_mq_free_rq_map (hctx->sched_tags); - hctx->sched_tags =NULL ; - } - } +queue_for_each_hw_ctx (q, hctx, i) + hctx->sched_tags =NULL ;if (blk_mq_is_shared_tags (flags)) -blk_mq_exit_sched_shared_tags (q); -} - -static int blk_mq_init_sched_shared_tags (struct request_queue *queue) -{ -struct blk_mq_tag_set *set = queue->tag_set; - -/* -* Set initial depth at max so that we don't need to reallocate for -* updating nr_requests. -*/ - queue->sched_shared_tags =blk_mq_alloc_map_and_rqs (set, -BLK_MQ_NO_HCTX_IDX , -MAX_SCHED_RQ ); -if (!queue->sched_shared_tags) -return -ENOMEM ; - -blk_mq_tag_update_sched_shared_tags (queue); - -return 0 ; + q->sched_shared_tags =NULL ; }void blk_mq_sched_reg_debugfs (struct request_queue *q)
@@ -458,8 +411,75 @@ void blk_mq_sched_unreg_debugfs(struct request_queue *q)mutex_unlock (&q->debugfs_mutex); } +void blk_mq_free_sched_tags (struct elevator_tags *et, +struct blk_mq_tag_set *set) +{ +unsigned long i; + +/* Shared tags are stored at index 0 in @tags. */ +if (blk_mq_is_shared_tags (set->flags)) +blk_mq_free_map_and_rqs (set, et->tags[0 ],BLK_MQ_NO_HCTX_IDX ); +else { +for (i =0 ; i < et->nr_hw_queues; i++) +blk_mq_free_map_and_rqs (set, et->tags[i], i); + } + +kfree (et); +} + +struct elevator_tags *blk_mq_alloc_sched_tags (struct blk_mq_tag_set *set, +unsigned int nr_hw_queues) +{ +unsigned int nr_tags; +int i; +struct elevator_tags *et; +gfp_t gfp =GFP_NOIO | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY; + +if (blk_mq_is_shared_tags (set->flags)) + nr_tags =1 ; +else + nr_tags = nr_hw_queues; + + et =kmalloc (sizeof (struct elevator_tags ) + + nr_tags *sizeof (struct blk_mq_tags *), gfp); +if (!et) +return NULL ; +/* +* Default to double of smaller one between hw queue_depth and +* 128, since we don't split into sync/async like the old code +* did. Additionally, this is a per-hw queue depth. +*/ + et->nr_requests = 2 * min_t(unsigned int, set->queue_depth, +BLKDEV_DEFAULT_RQ ); + et->nr_hw_queues = nr_hw_queues; + +if (blk_mq_is_shared_tags (set->flags)) { +/* Shared tags are stored at index 0 in @tags. */ + et->tags[0 ] =blk_mq_alloc_map_and_rqs (set,BLK_MQ_NO_HCTX_IDX , +MAX_SCHED_RQ ); +if (!et->tags[0 ]) + goto out; + }else { +for (i =0 ; i < et->nr_hw_queues; i++) { + et->tags[i] =blk_mq_alloc_map_and_rqs (set, i, + et->nr_requests); +if (!et->tags[i]) + goto out_unwind; + } + } + +return et; +out_unwind: +while (--i >=0 ) +blk_mq_free_map_and_rqs (set, et->tags[i], i); +out: +kfree (et); +return NULL ; +} +/* caller must have a reference to @e, will grab another one if successful */ -int blk_mq_init_sched (struct request_queue *q,struct elevator_type *e) +int blk_mq_init_sched (struct request_queue *q,struct elevator_type *e, +struct elevator_tags *et) {unsigned int flags = q->tag_set->flags;struct blk_mq_hw_ctx *hctx;
@@ -467,40 +487,33 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)unsigned long i;int ret; -/* -* Default to double of smaller one between hw queue_depth and 128, -* since we don't split into sync/async like the old code did. -* Additionally, this is a per-hw queue depth. -*/ - q->nr_requests = 2 * min_t(unsigned int, q->tag_set->queue_depth, -BLKDEV_DEFAULT_RQ ); - - eq =elevator_alloc (q, e); + eq =elevator_alloc (q, e, et);if (!eq)return -ENOMEM ; + q->nr_requests = et->nr_requests; +if (blk_mq_is_shared_tags (flags)) { - ret =blk_mq_init_sched_shared_tags (q); -if (ret) - goto err_put_elevator; +/* Shared tags are stored at index 0 in @et->tags. */ + q->sched_shared_tags = et->tags[0 ]; +blk_mq_tag_update_sched_shared_tags (q); }queue_for_each_hw_ctx (q, hctx, i) { - ret =blk_mq_sched_alloc_map_and_rqs (q, hctx, i); -if (ret) - goto err_free_map_and_rqs; +if (blk_mq_is_shared_tags (flags)) + hctx->sched_tags = q->sched_shared_tags; +else + hctx->sched_tags = et->tags[i]; } ret = e->ops.init_sched (q, eq);if (ret) - goto err_free_map_and_rqs; + goto out;queue_for_each_hw_ctx (q, hctx, i) {if (e->ops.init_hctx) { ret = e->ops.init_hctx (hctx, i);if (ret) { - eq = q->elevator; -blk_mq_sched_free_rqs (q);blk_mq_exit_sched (q, eq);kobject_put (&eq->kobj);return ret;
@@ -509,10 +522,8 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) }return 0 ; -err_free_map_and_rqs: -blk_mq_sched_free_rqs (q); +out:blk_mq_sched_tags_teardown (q, flags); -err_put_elevator:kobject_put (&eq->kobj); q->elevator =NULL ;return ret;
block/blk-mq-sched.h +7 -1
@@ -18,10 +18,16 @@ void __blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx);void blk_mq_sched_dispatch_requests (struct blk_mq_hw_ctx *hctx); -int blk_mq_init_sched (struct request_queue *q,struct elevator_type *e); +int blk_mq_init_sched (struct request_queue *q,struct elevator_type *e, +struct elevator_tags *et);void blk_mq_exit_sched (struct request_queue *q,struct elevator_queue *e);void blk_mq_sched_free_rqs (struct request_queue *q); +struct elevator_tags *blk_mq_alloc_sched_tags (struct blk_mq_tag_set *set, +unsigned int nr_hw_queues); +void blk_mq_free_sched_tags (struct elevator_tags *et, +struct blk_mq_tag_set *set); +static inline void blk_mq_sched_restart (struct blk_mq_hw_ctx *hctx) {if (test_bit (BLK_MQ_S_SCHED_RESTART , &hctx->state))
block/elevator.c +34 -6
@@ -54,6 +54,8 @@ struct elv_change_ctx {struct elevator_queue *old;/* for registering new elevator */ struct elevator_queue *new; +/* holds sched tags data */ +struct elevator_tags *et; };static DEFINE_SPINLOCK (elv_list_lock);
@@ -132,7 +134,7 @@ static struct elevator_type *elevator_find_get(const char *name)static const struct kobj_type elv_ktype;struct elevator_queue *elevator_alloc (struct request_queue *q, -struct elevator_type *e) +struct elevator_type *e,struct elevator_tags *et) {struct elevator_queue *eq;
@@ -145,6 +147,7 @@ struct elevator_queue *elevator_alloc(struct request_queue *q,kobject_init (&eq->kobj, &elv_ktype);mutex_init (&eq->sysfs_lock);hash_init (eq->hash); + eq->et = et;return eq; }
@@ -165,7 +168,6 @@ static void elevator_exit(struct request_queue *q)lockdep_assert_held (&q->elevator_lock);ioc_clear_queue (q); -blk_mq_sched_free_rqs (q);mutex_lock (&e->sysfs_lock);blk_mq_exit_sched (q, e);
@@ -591,7 +593,7 @@ static int elevator_switch(struct request_queue *q, struct elv_change_ctx *ctx) }if (new_e) { - ret =blk_mq_init_sched (q, new_e); + ret =blk_mq_init_sched (q, new_e, ctx->et);if (ret) goto out_unfreeze; ctx->new = q->elevator;
@@ -626,8 +628,10 @@ static void elv_exit_and_release(struct request_queue *q)elevator_exit (q);mutex_unlock (&q->elevator_lock);blk_mq_unfreeze_queue (q, memflags); -if (e) +if (e) { +blk_mq_free_sched_tags (e->et, q->tag_set);kobject_put (&e->kobj); + } } static int elevator_change_done(struct request_queue *q,
@@ -640,6 +644,7 @@ static int elevator_change_done(struct request_queue *q, &ctx->old->flags);elv_unregister_queue (q, ctx->old); +blk_mq_free_sched_tags (ctx->old->et, q->tag_set);kobject_put (&ctx->old->kobj);if (enable_wbt)wbt_enable_default (q->disk);
@@ -658,9 +663,16 @@ static int elevator_change_done(struct request_queue *q,static int elevator_change (struct request_queue *q,struct elv_change_ctx *ctx) {unsigned int memflags; +struct blk_mq_tag_set *set = q->tag_set;int ret =0 ; -lockdep_assert_held (&q->tag_set->update_nr_hwq_lock); +lockdep_assert_held (&set->update_nr_hwq_lock); + +if (strncmp (ctx->name,"none" ,4 )) { + ctx->et =blk_mq_alloc_sched_tags (set, set->nr_hw_queues); +if (!ctx->et) +return -ENOMEM ; + } memflags =blk_mq_freeze_queue (q);/*
@@ -680,6 +692,11 @@ static int elevator_change(struct request_queue *q, struct elv_change_ctx *ctx)blk_mq_unfreeze_queue (q, memflags);if (!ret) ret =elevator_change_done (q, ctx); +/* +* Free sched tags if it's allocated but we couldn't switch elevator. +*/ +if (ctx->et && !ctx->new) +blk_mq_free_sched_tags (ctx->et, set);return ret; }
@@ -690,6 +707,7 @@ static int elevator_change(struct request_queue *q, struct elv_change_ctx *ctx)*/ void elv_update_nr_hw_queues (struct request_queue *q,struct elevator_type *e) { +struct blk_mq_tag_set *set = q->tag_set;struct elv_change_ctx ctx = {};int ret = -ENODEV ;
@@ -697,15 +715,25 @@ void elv_update_nr_hw_queues(struct request_queue *q, struct elevator_type *e)if (e && !blk_queue_dying (q) &&blk_queue_registered (q)) { ctx.name = e->elevator_name; - + ctx.et =blk_mq_alloc_sched_tags (set, set->nr_hw_queues); +if (!ctx.et) { +WARN_ON_ONCE (1 ); + goto unfreeze; + }mutex_lock (&q->elevator_lock);/* force to reattach elevator after nr_hw_queue is updated */ ret =elevator_switch (q, &ctx);mutex_unlock (&q->elevator_lock); } +unfreeze:blk_mq_unfreeze_queue_nomemrestore (q);if (!ret)WARN_ON_ONCE (elevator_change_done (q, &ctx)); +/* +* Free sched tags if it's allocated but we couldn't switch elevator. +*/ +if (ctx.et && !ctx.new) +blk_mq_free_sched_tags (ctx.et, set); }/*
block/elevator.h +12 -2
@@ -23,6 +23,15 @@ enum elv_merge {struct blk_mq_alloc_data ;struct blk_mq_hw_ctx ; +struct elevator_tags { +/* num. of hardware queues for which tags are allocated */ +unsigned int nr_hw_queues; +/* depth used while allocating tags */ +unsigned int nr_requests; +/* shared tag is stored at index 0 */ +struct blk_mq_tags *tags[]; +}; +struct elevator_mq_ops {int (*init_sched)(struct request_queue *,struct elevator_queue *);void (*exit_sched)(struct elevator_queue *);
@@ -113,6 +122,7 @@ struct request *elv_rqhash_find(struct request_queue *q, sector_t offset);struct elevator_queue {struct elevator_type *type; +struct elevator_tags *et;void *elevator_data;struct kobject kobj;struct mutex sysfs_lock;
@@ -152,8 +162,8 @@ ssize_t elv_iosched_show(struct gendisk *disk, char *page);ssize_t elv_iosched_store (struct gendisk *disk,const char *page,size_t count);extern bool elv_bio_merge_ok (struct request *,struct bio *); -extern struct elevator_queue *elevator_alloc (struct request_queue *, -struct elevator_type *); +struct elevator_queue *elevator_alloc (struct request_queue *, +struct elevator_type *,struct elevator_tags *);/* * Helper functions.
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 442/457 block: fix potential deadlock while running nr_hw_queue update
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit 04225d13aef11b2a539014def5e47d8c21fd74a5 ]
Move scheduler tags (sched_tags) allocation and deallocation outside both the ->elevator_lock and ->freeze_lock when updating nr_hw_queues. This change breaks the dependency chain from the percpu allocator lock to the elevator lock, helping to prevent potential deadlocks, as observed in the reported lockdep splat[1].
This commit introduces batch allocation and deallocation helpers for sched_tags, which are now used from within __blk_mq_update_nr_hw_queues routine while iterating through the tagset.
With this change, all sched_tags memory management is handled entirely outside the ->elevator_lock and the ->freeze_lock context, thereby eliminating the lock dependency that could otherwise manifest during nr_hw_queues updates.
[1] https://lore.kernel.org/all/[email protected]/
Stable-dep-of: 2d82f3bd8910 ("blk-mq: fix lockdep warning in __blk_mq_update_nr_hw_queues")
--- block/blk-mq-sched.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ block/blk-mq-sched.h | 4 +++ block/blk-mq.c | 16 +++++++---- block/blk.h | 4 ++- block/elevator.c | 15 ++++------ 5 files changed, 89 insertions(+), 15 deletions(-)
block/blk-mq-sched.c +65 -0
@@ -427,6 +427,32 @@ void blk_mq_free_sched_tags(struct elevator_tags *et,kfree (et); } +void blk_mq_free_sched_tags_batch (struct xarray *et_table, +struct blk_mq_tag_set *set) +{ +struct request_queue *q; +struct elevator_tags *et; + +lockdep_assert_held_write (&set->update_nr_hwq_lock); + +list_for_each_entry (q, &set->tag_list, tag_set_list) { +/* +* Accessing q->elevator without holding q->elevator_lock is +* safe because we're holding here set->update_nr_hwq_lock in +* the writer context. So, scheduler update/switch code (which +* acquires the same lock but in the reader context) can't run +* concurrently. +*/ +if (q->elevator) { + et =xa_load (et_table, q->id); +if (unlikely (!et)) +WARN_ON_ONCE (1 ); +else +blk_mq_free_sched_tags (et, set); + } + } +} +struct elevator_tags *blk_mq_alloc_sched_tags (struct blk_mq_tag_set *set,unsigned int nr_hw_queues) {
@@ -477,6 +503,45 @@ struct elevator_tags *blk_mq_alloc_sched_tags(struct blk_mq_tag_set *set,return NULL ; } +int blk_mq_alloc_sched_tags_batch (struct xarray *et_table, +struct blk_mq_tag_set *set,unsigned int nr_hw_queues) +{ +struct request_queue *q; +struct elevator_tags *et; +gfp_t gfp =GFP_NOIO | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY; + +lockdep_assert_held_write (&set->update_nr_hwq_lock); + +list_for_each_entry (q, &set->tag_list, tag_set_list) { +/* +* Accessing q->elevator without holding q->elevator_lock is +* safe because we're holding here set->update_nr_hwq_lock in +* the writer context. So, scheduler update/switch code (which +* acquires the same lock but in the reader context) can't run +* concurrently. +*/ +if (q->elevator) { + et =blk_mq_alloc_sched_tags (set, nr_hw_queues); +if (!et) + goto out_unwind; +if (xa_insert (et_table, q->id, et, gfp)) + goto out_free_tags; + } + } +return 0 ; +out_free_tags: +blk_mq_free_sched_tags (et, set); +out_unwind: +list_for_each_entry_continue_reverse (q, &set->tag_list, tag_set_list) { +if (q->elevator) { + et =xa_load (et_table, q->id); +if (et) +blk_mq_free_sched_tags (et, set); + } + } +return -ENOMEM ; +} +/* caller must have a reference to @e, will grab another one if successful */ int blk_mq_init_sched (struct request_queue *q,struct elevator_type *e,struct elevator_tags *et)
block/blk-mq-sched.h +4 -0
@@ -25,8 +25,12 @@ void blk_mq_sched_free_rqs(struct request_queue *q);struct elevator_tags *blk_mq_alloc_sched_tags (struct blk_mq_tag_set *set,unsigned int nr_hw_queues); +int blk_mq_alloc_sched_tags_batch (struct xarray *et_table, +struct blk_mq_tag_set *set,unsigned int nr_hw_queues);void blk_mq_free_sched_tags (struct elevator_tags *et,struct blk_mq_tag_set *set); +void blk_mq_free_sched_tags_batch (struct xarray *et_table, +struct blk_mq_tag_set *set);static inline void blk_mq_sched_restart (struct blk_mq_hw_ctx *hctx) {
block/blk-mq.c +11 -5
@@ -4972,12 +4972,13 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr)* Switch back to the elevator type stored in the xarray. */ static void blk_mq_elv_switch_back (struct request_queue *q, -struct xarray *elv_tbl) +struct xarray *elv_tbl,struct xarray *et_tbl) {struct elevator_type *e =xa_load (elv_tbl, q->id); +struct elevator_tags *t =xa_load (et_tbl, q->id);/* The elv_update_nr_hw_queues unfreezes the queue. */ -elv_update_nr_hw_queues (q, e); +elv_update_nr_hw_queues (q, e, t);/* Drop the reference acquired in blk_mq_elv_switch_none. */ if (e)
@@ -5029,7 +5030,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,int prev_nr_hw_queues = set->nr_hw_queues;unsigned int memflags;int i; -struct xarray elv_tbl; +struct xarray elv_tbl, et_tbl;lockdep_assert_held (&set->tag_list_lock);
@@ -5042,6 +5043,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, memflags =memalloc_noio_save (); +xa_init (&et_tbl); +if (blk_mq_alloc_sched_tags_batch (&et_tbl, set, nr_hw_queues) <0 ) + goto out_memalloc_restore; +xa_init (&elv_tbl);list_for_each_entry (q, &set->tag_list, tag_set_list) {
@@ -5085,7 +5090,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, switch_back:/* The blk_mq_elv_switch_back unfreezes queue for us. */ list_for_each_entry (q, &set->tag_list, tag_set_list) -blk_mq_elv_switch_back (q, &elv_tbl); +blk_mq_elv_switch_back (q, &elv_tbl, &et_tbl);list_for_each_entry (q, &set->tag_list, tag_set_list) {blk_mq_sysfs_register_hctxs (q);
@@ -5096,7 +5101,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, }xa_destroy (&elv_tbl); - +xa_destroy (&et_tbl); +out_memalloc_restore:memalloc_noio_restore (memflags);/* Free the excess tags when nr_hw_queues shrink. */
block/blk.h +3 -1
@@ -12,6 +12,7 @@#include "blk-crypto-internal.h" struct elevator_type ; +struct elevator_tags ;#define BLK_DEV_MAX_SECTORS (LLONG_MAX >> 9)#define BLK_MIN_SEGMENT_SIZE 4096
@@ -322,7 +323,8 @@ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list,bool blk_insert_flush (struct request *rq); -void elv_update_nr_hw_queues (struct request_queue *q,struct elevator_type *e); +void elv_update_nr_hw_queues (struct request_queue *q,struct elevator_type *e, +struct elevator_tags *t);void elevator_set_default (struct request_queue *q);void elevator_set_none (struct request_queue *q);
block/elevator.c +6 -9
@@ -705,7 +705,8 @@ static int elevator_change(struct request_queue *q, struct elv_change_ctx *ctx)* The I/O scheduler depends on the number of hardware queues, this forces a * reattachment when nr_hw_queues changes. */ -void elv_update_nr_hw_queues (struct request_queue *q,struct elevator_type *e) +void elv_update_nr_hw_queues (struct request_queue *q,struct elevator_type *e, +struct elevator_tags *t) {struct blk_mq_tag_set *set = q->tag_set;struct elv_change_ctx ctx = {};
@@ -715,25 +716,21 @@ void elv_update_nr_hw_queues(struct request_queue *q, struct elevator_type *e)if (e && !blk_queue_dying (q) &&blk_queue_registered (q)) { ctx.name = e->elevator_name; - ctx.et =blk_mq_alloc_sched_tags (set, set->nr_hw_queues); -if (!ctx.et) { -WARN_ON_ONCE (1 ); - goto unfreeze; - } + ctx.et = t; +mutex_lock (&q->elevator_lock);/* force to reattach elevator after nr_hw_queue is updated */ ret =elevator_switch (q, &ctx);mutex_unlock (&q->elevator_lock); } -unfreeze:blk_mq_unfreeze_queue_nomemrestore (q);if (!ret)WARN_ON_ONCE (elevator_change_done (q, &ctx));/* * Free sched tags if it's allocated but we couldn't switch elevator. */ -if (ctx.et && !ctx.new) -blk_mq_free_sched_tags (ctx.et, set); +if (t && !ctx.new) +blk_mq_free_sched_tags (t, set); }/*
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 443/457 blk-mq: fix lockdep warning in __blk_mq_update_nr_hw_queues
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei <[email protected]>
[ Upstream commit 2d82f3bd8910eb65e30bb2a3c9b945bfb3b6d661 ]
Commit 5989bfe6ac6b ("block: restore two stage elevator switch while running nr_hw_queue update") reintroduced a lockdep warning by calling blk_mq_freeze_queue_nomemsave() before switching the I/O scheduler.
The function blk_mq_elv_switch_none() calls elevator_change_done(). Running this while the queue is frozen causes a lockdep warning.
Fix this by reordering the operations: first, switch the I/O scheduler to 'none', and then freeze the queue. This ensures that elevator_change_done() is not called on an already frozen queue. And this way is safe because elevator_set_none() does freeze queue before switching to none.
Also we still have to rely on blk_mq_elv_switch_back() for switching back, and it has to cover unfrozen queue case.
--- block/blk-mq.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
block/blk-mq.c +9 -4
@@ -5031,6 +5031,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,unsigned int memflags;int i;struct xarray elv_tbl, et_tbl; +bool queues_frozen = false;lockdep_assert_held (&set->tag_list_lock);
@@ -5054,9 +5055,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,blk_mq_sysfs_unregister_hctxs (q); } -list_for_each_entry (q, &set->tag_list, tag_set_list) -blk_mq_freeze_queue_nomemsave (q); -/* * Switch IO scheduler to 'none', cleaning up the data associated * with the previous scheduler. We will switch back once we are done
@@ -5066,6 +5064,9 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,if (blk_mq_elv_switch_none (q, &elv_tbl)) goto switch_back; +list_for_each_entry (q, &set->tag_list, tag_set_list) +blk_mq_freeze_queue_nomemsave (q); + queues_frozen = true;if (blk_mq_realloc_tag_set_tags (set, nr_hw_queues) <0 ) goto switch_back;
@@ -5089,8 +5090,12 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, } switch_back:/* The blk_mq_elv_switch_back unfreezes queue for us. */ -list_for_each_entry (q, &set->tag_list, tag_set_list) +list_for_each_entry (q, &set->tag_list, tag_set_list) { +/* switch_back expects queue to be frozen */ +if (!queues_frozen) +blk_mq_freeze_queue_nomemsave (q);blk_mq_elv_switch_back (q, &elv_tbl, &et_tbl); + }list_for_each_entry (q, &set->tag_list, tag_set_list) {blk_mq_sysfs_register_hctxs (q);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 444/457 block: decrement block_rq_qos static key in rq_qos_del()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit ade1beea1c27657712aa8f594226d461639382ff ]
rq_qos_add() increments the block_rq_qos static key when a QoS policy is attached. When a QoS policy is removed via rq_qos_del(), we must symmetrically decrement the static key. If this removal drops the last QoS policy from the queue (q->rq_qos becomes NULL), the static branch can be disabled and the jump label patched to a NOP, avoiding overhead on the hot path.
This change ensures rq_qos_add()/rq_qos_del() keep the block_rq_qos static key balanced and prevents leaving the branch permanently enabled after the last policy is removed.
--- block/blk-rq-qos.c | 1 + 1 file changed, 1 insertion(+)
block/blk-rq-qos.c +1 -0
@@ -374,6 +374,7 @@ void rq_qos_del(struct rq_qos *rqos)for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) {if (*cur == rqos) { *cur = rqos->next; +static_branch_dec (&block_rq_qos);break ; } }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 445/457 block: skip q->rq_qos check in rq_qos_done_bio()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit 275332877e2fa9d6efa7402b1e897f6c6ee695bb ]
If a bio has BIO_QOS_THROTTLED or BIO_QOS_MERGED set, it implicitly guarantees that q->rq_qos is present. Avoid re-checking q->rq_qos in this case and call __rq_qos_done_bio() directly as a minor optimization.
Stable-dep-of: 370ac285f23a ("block: avoid cpu_hotplug_lock depedency on freeze_lock")
--- block/blk-rq-qos.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
block/blk-rq-qos.h +8 -2
@@ -142,8 +142,14 @@ static inline void rq_qos_done_bio(struct bio *bio) bio->bi_bdev && (bio_flagged(bio, BIO_QOS_THROTTLED) || bio_flagged(bio, BIO_QOS_MERGED))) {struct request_queue *q =bdev_get_queue (bio->bi_bdev); -if (q->rq_qos) -__rq_qos_done_bio (q->rq_qos, bio); + +/* +* If a bio has BIO_QOS_xxx set, it implicitly implies that +* q->rq_qos is present. So, we skip re-checking q->rq_qos +* here as an extra optimization and directly call +* __rq_qos_done_bio(). +*/ +__rq_qos_done_bio (q->rq_qos, bio); } }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 446/457 block: avoid cpu_hotplug_lock depedency on freeze_lock
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit 370ac285f23aecae40600851fb4a1a9e75e50973 ]
A recent lockdep[1] splat observed while running blktest block/005 reveals a potential deadlock caused by the cpu_hotplug_lock dependency on ->freeze_lock. This dependency was introduced by commit 033b667a823e ("block: blk-rq-qos: guard rq-qos helpers by static key").
That change added a static key to avoid fetching q->rq_qos when neither blk-wbt nor blk-iolatency is configured. The static key dynamically patches kernel text to a NOP when disabled, eliminating overhead of fetching q->rq_qos in the I/O hot path. However, enabling a static key at runtime requires acquiring both cpu_hotplug_lock and jump_label_mutex. When this happens after the queue has already been frozen (i.e., while holding ->freeze_lock), it creates a locking dependency from cpu_hotplug_lock to ->freeze_lock, which leads to a potential deadlock reported by lockdep [1].
To resolve this, replace the static key mechanism with q->queue_flags:QUEUE_FLAG_QOS_ENABLED. This flag is evaluated in the fast path before accessing q->rq_qos. If the flag is set, we proceed to fetch q->rq_qos; otherwise, the access is skipped.
Since q->queue_flags is commonly accessed in IO hotpath and resides in the first cacheline of struct request_queue, checking it imposes minimal overhead while eliminating the deadlock risk.
This change avoids the lockdep splat without introducing performance regressions.
[1] https://lore.kernel.org/linux-block/4fdm37so3o4xricdgfosgmohn63aa7wj3ua4e5vpihoamwg3ui@fq42f5q5t5ic/
--- block/blk-mq-debugfs.c | 1 + block/blk-rq-qos.c | 9 ++++--- block/blk-rq-qos.h | 54 ++++++++++++++++++++++++------------------ include/linux/blkdev.h | 1 + 4 files changed, 37 insertions(+), 28 deletions(-)
block/blk-mq-debugfs.c +1 -0
@@ -95,6 +95,7 @@ static const char *const blk_queue_flag_name[] = {QUEUE_FLAG_NAME (SQ_SCHED ),QUEUE_FLAG_NAME (DISABLE_WBT_DEF ),QUEUE_FLAG_NAME (NO_ELV_SWITCH ), + QUEUE_FLAG_NAME(QOS_ENABLED), };#undef QUEUE_FLAG_NAME
block/blk-rq-qos.c +4 -5
@@ -2,8 +2,6 @@#include "blk-rq-qos.h" -__read_mostly DEFINE_STATIC_KEY_FALSE (block_rq_qos); -/* * Increment 'v', if 'v' is below 'below'. Returns true if we succeeded, * false if 'v' + 1 would be bigger than 'below'.
@@ -319,8 +317,8 @@ void rq_qos_exit(struct request_queue *q)struct rq_qos *rqos = q->rq_qos; q->rq_qos = rqos->next; rqos->ops->exit (rqos); -static_branch_dec (&block_rq_qos); } +blk_queue_flag_clear (QUEUE_FLAG_QOS_ENABLED , q);mutex_unlock (&q->rq_qos_mutex); }
@@ -346,7 +344,7 @@ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id, goto ebusy; rqos->next = q->rq_qos; q->rq_qos = rqos; -static_branch_inc (&block_rq_qos); +blk_queue_flag_set (QUEUE_FLAG_QOS_ENABLED , q);blk_mq_unfreeze_queue (q, memflags);
@@ -374,10 +372,11 @@ void rq_qos_del(struct rq_qos *rqos)for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) {if (*cur == rqos) { *cur = rqos->next; -static_branch_dec (&block_rq_qos);break ; } } +if (!q->rq_qos) +blk_queue_flag_clear (QUEUE_FLAG_QOS_ENABLED , q);blk_mq_unfreeze_queue (q, memflags);mutex_lock (&q->debugfs_mutex);
block/blk-rq-qos.h +31 -23
108 lines not on this page · raw message
include/linux/blkdev.h +1 -0
@@ -652,6 +652,7 @@ enum {QUEUE_FLAG_SQ_SCHED ,/* single queue style io dispatch */ QUEUE_FLAG_DISABLE_WBT_DEF ,/* for sched to disable/enable wbt */ QUEUE_FLAG_NO_ELV_SWITCH ,/* can't switch elevator any more */ +QUEUE_FLAG_QOS_ENABLED ,/* qos is enabled */ QUEUE_FLAG_MAX };
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 447/457 Octeontx2-af: Skip overlap check for SPI field
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hariprasad Kelam <[email protected]>
[ Upstream commit 8c5d95988c34f0aeba1f34cd5e4ba69494c90c5f ]
Octeontx2/CN10K silicon supports generating a 256-bit key per packet. The specific fields to be extracted from a packet for key generation are configurable via a Key Extraction (MKEX) Profile.
The AF driver scans the configured extraction profile to ensure that fields from upper layers do not overwrite fields from lower layers in the key.
Example Packet Field Layout:
LA: DMAC + SMAC
LB: VLAN
LC: IPv4/IPv6
LD: TCP/UDP
Valid MKEX Profile Configuration:
LA -> DMAC -> key_offset[0-5] LC -> SIP -> key_offset[20-23] LD -> SPORT -> key_offset[30-31]
Invalid MKEX profile configuration:
LA -> DMAC -> key_offset[0-5] LC -> SIP -> key_offset[20-23] LD -> SPORT -> key_offset[2-3] // Overlaps with DMAC field
In another scenario, if the MKEX profile is configured to extract the SPI field from both AH and ESP headers at the same key offset, the driver rejecting this configuration. In a regular traffic, ipsec packet will be having either AH(LD) or ESP (LE). This patch relaxes the check for the same.
--- drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +2 -2
@@ -606,8 +606,8 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)if (!npc_check_field (rvu, blkaddr,NPC_LB , intf)) *features &= ~BIT_ULL (NPC_OUTER_VID ); -/* Set SPI flag only if AH/ESP and IPSEC_SPI are in the key */ -if (npc_check_field (rvu, blkaddr,NPC_IPSEC_SPI , intf) && +/* Allow extracting SPI field from AH and ESP headers at same offset */ +if (npc_is_field_present (rvu,NPC_IPSEC_SPI , intf) && (*features & (BIT_ULL (NPC_IPPROTO_ESP ) |BIT_ULL (NPC_IPPROTO_AH )))) *features |=BIT_ULL (NPC_IPSEC_SPI );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 448/457 net/mlx5: Base ECVF devlink port attrs from 0
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Jurgens <[email protected]>
[ Upstream commit bc17455bc843b2f4b206e0bb8139013eb3d3c08b ]
Adjust the vport number by the base ECVF vport number so the port attributes start at 0. Previously the port attributes would start 1 after the maximum number of host VFs.
--- drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c +3 -1
@@ -47,10 +47,12 @@ static void mlx5_esw_offloads_pf_vf_devlink_port_attrs_set(struct mlx5_eswitch *devlink_port_attrs_pci_vf_set (dl_port, controller_num, pfnum, vport_num -1 , external); }else if (mlx5_core_is_ec_vf_vport (esw->dev, vport_num)) { +u16 base_vport =mlx5_core_ec_vf_vport_base (dev); +memcpy (dl_port->attrs.switch_id.id, ppid.id, ppid.id_len); dl_port->attrs.switch_id.id_len = ppid.id_len;devlink_port_attrs_pci_vf_set (dl_port,0 , pfnum, - vport_num -1 , false); + vport_num - base_vport, false); } }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 449/457 net/mlx5: Add IFC bits and enums for buf_ownership
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oren Sidi <[email protected]>
[ Upstream commit 6f09ee0b583cad4f2b6a82842c26235bee3d5c2e ]
Extend structure layouts and defines buf_ownership. buf_ownership indicates whether the buffer is managed by SW or FW.
Stable-dep-of: 451d2849ea66 ("net/mlx5e: Query FW for buffer ownership")
--- include/linux/mlx5/mlx5_ifc.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
include/linux/mlx5/mlx5_ifc.h +12 -2
@@ -10460,8 +10460,16 @@ struct mlx5_ifc_pifr_reg_bits {u8 port_filter_update_en[8 ][0x20 ]; }; +enum { +MLX5_BUF_OWNERSHIP_UNKNOWN =0x0 , +MLX5_BUF_OWNERSHIP_FW_OWNED =0x1 , +MLX5_BUF_OWNERSHIP_SW_OWNED =0x2 , +}; +struct mlx5_ifc_pfcc_reg_bits { -u8 reserved_at_0[0x8 ]; +u8 reserved_at_0[0x4 ]; +u8 buf_ownership[0x2 ]; +u8 reserved_at_6[0x2 ];u8 local_port[0x8 ];u8 reserved_at_10[0xb ];u8 ppan_mask_n[0x1 ];
@@ -10597,7 +10605,9 @@ struct mlx5_ifc_pcam_enhanced_features_bits {u8 fec_200G_per_lane_in_pplm[0x1 ];u8 reserved_at_1e[0x2a ];u8 fec_100G_per_lane_in_pplm[0x1 ]; -u8 reserved_at_49[0x1f ]; +u8 reserved_at_49[0xa ]; +u8 buffer_ownership[0x1 ]; +u8 resereved_at_54[0x14 ];u8 fec_50G_per_lane_in_pplm[0x1 ];u8 reserved_at_69[0x4 ];u8 rx_icrc_encapsulated_counter[0x1 ];
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 450/457 net/mlx5e: Query FW for buffer ownership
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Lazar <[email protected]>
[ Upstream commit 451d2849ea66659040b59ae3cb7e50cc97404733 ]
The SW currently saves local buffer ownership when setting the buffer.
This means that the SW assumes it has ownership of the buffer after the command is set.
If setting the buffer fails and we remain in FW ownership, the local buffer ownership state incorrectly remains as SW-owned. This leads to incorrect behavior in subsequent PFC commands, causing failures.
Instead of saving local buffer ownership in SW, query the FW for buffer ownership when setting the buffer. This ensures that the buffer ownership state is accurately reflected, avoiding the issues caused by incorrect ownership states.
--- .../ethernet/mellanox/mlx5/core/en/dcbnl.h | 1 - .../ethernet/mellanox/mlx5/core/en_dcbnl.c | 12 ++++++++--- .../ethernet/mellanox/mlx5/core/mlx5_core.h | 2 ++ .../net/ethernet/mellanox/mlx5/core/port.c | 20 +++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/dcbnl.h +0 -1
@@ -26,7 +26,6 @@ struct mlx5e_dcbx {u8 cap;/* Buffer configuration */ -bool manual_buffer;u32 cable_len;u32 xoff;u16 port_buff_cell_sz;
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +9 -3
@@ -362,6 +362,7 @@ static int mlx5e_dcbnl_ieee_getpfc(struct net_device *dev,static int mlx5e_dcbnl_ieee_setpfc (struct net_device *dev,struct ieee_pfc *pfc) { +u8 buffer_ownership =MLX5_BUF_OWNERSHIP_UNKNOWN ;struct mlx5e_priv *priv =netdev_priv (dev);struct mlx5_core_dev *mdev = priv->mdev;u32 old_cable_len = priv->dcbx.cable_len;
@@ -389,7 +390,14 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,if (MLX5_BUFFER_SUPPORTED (mdev)) { pfc_new.pfc_en = (changed &MLX5E_PORT_BUFFER_PFC ) ? pfc->pfc_en : curr_pfc_en; -if (priv->dcbx.manual_buffer) + ret =mlx5_query_port_buffer_ownership (mdev, + &buffer_ownership); +if (ret) +netdev_err (dev, +"%s, Failed to get buffer ownership: %d\n" , + __func__, ret); + +if (buffer_ownership ==MLX5_BUF_OWNERSHIP_SW_OWNED ) ret =mlx5e_port_manual_buffer_config (priv, changed, dev->mtu, &pfc_new,NULL ,NULL );
@@ -982,7 +990,6 @@ static int mlx5e_dcbnl_setbuffer(struct net_device *dev,if (!changed)return 0 ; - priv->dcbx.manual_buffer = true; err =mlx5e_port_manual_buffer_config (priv, changed, dev->mtu,NULL , buffer_size, prio2buffer);return err;
@@ -1252,7 +1259,6 @@ void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv) priv->dcbx.cap |=DCB_CAP_DCBX_HOST ; priv->dcbx.port_buff_cell_sz =mlx5e_query_port_buffers_cell_size (priv); - priv->dcbx.manual_buffer = false; priv->dcbx.cable_len =MLX5E_DEFAULT_CABLE_LEN ;mlx5e_ets_init (priv);
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +2 -0
@@ -358,6 +358,8 @@ int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);int mlx5_set_port_dcbx_param (struct mlx5_core_dev *mdev,u32 *in);int mlx5_set_trust_state (struct mlx5_core_dev *mdev,u8 trust_state);int mlx5_query_trust_state (struct mlx5_core_dev *mdev,u8 *trust_state); +int mlx5_query_port_buffer_ownership (struct mlx5_core_dev *mdev, +u8 *buffer_ownership);int mlx5_set_dscp2prio (struct mlx5_core_dev *mdev,u8 dscp,u8 prio);int mlx5_query_dscp2prio (struct mlx5_core_dev *mdev,u8 *dscp2prio);
drivers/net/ethernet/mellanox/mlx5/core/port.c +20 -0
@@ -968,6 +968,26 @@ int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state)return err; } +int mlx5_query_port_buffer_ownership (struct mlx5_core_dev *mdev, +u8 *buffer_ownership) +{ +u32 out[MLX5_ST_SZ_DW (pfcc_reg)] = {}; +int err; + +if (!MLX5_CAP_PCAM_FEATURE (mdev, buffer_ownership)) { + *buffer_ownership =MLX5_BUF_OWNERSHIP_UNKNOWN ; +return 0 ; + } + + err =mlx5_query_pfcc_reg (mdev, out,sizeof (out)); +if (err) +return err; + + *buffer_ownership =MLX5_GET (pfcc_reg, out, buf_ownership); + +return 0 ; +} +int mlx5_set_dscp2prio (struct mlx5_core_dev *mdev,u8 dscp,u8 prio) {int sz =MLX5_ST_SZ_BYTES (qpdpm_reg);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 451/457 net/mlx5e: Preserve shared buffer capacity during headroom updates
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armen Ratner <[email protected]>
[ Upstream commit 8b0587a885fdb34fd6090a3f8625cb7ac1444826 ]
When port buffer headroom changes, port_update_shared_buffer() recalculates the shared buffer size and splits it in a 3:1 ratio (lossy:lossless) - Currently, the calculation is:
lossless = shared / 4;
lossy = (shared / 4) * 3;
Meaning, the calculation dropped the remainder of shared % 4 due to integer division, unintentionally reducing the total shared buffer by up to three cells on each update. Over time, this could shrink the buffer below usable size.
Fix it by changing the calculation to:
lossless = shared / 4;
lossy = shared - lossless;
This retains all buffer cells while still approximating the intended 3:1 split, preventing capacity loss over time.
While at it, perform headroom calculations in units of cells rather than in bytes for more accurate calculations avoiding extra divisions.
--- .../mellanox/mlx5/core/en/port_buffer.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +8 -10
@@ -272,8 +272,8 @@ static int port_update_shared_buffer(struct mlx5_core_dev *mdev,/* Total shared buffer size is split in a ratio of 3:1 between * lossy and lossless pools respectively. */ - lossy_epool_size = (shared_buffer_size /4 ) *3 ; lossless_ipool_size = shared_buffer_size /4 ; + lossy_epool_size = shared_buffer_size - lossless_ipool_size;mlx5e_port_set_sbpr (mdev,0 ,MLX5_EGRESS_DIR ,MLX5_LOSSY_POOL ,0 , lossy_epool_size);
@@ -288,14 +288,12 @@ static int port_set_buffer(struct mlx5e_priv *priv,u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;struct mlx5_core_dev *mdev = priv->mdev;int sz =MLX5_ST_SZ_BYTES (pbmc_reg); -u32 new_headroom_size =0 ; -u32 current_headroom_size; +u32 current_headroom_cells =0 ; +u32 new_headroom_cells =0 ;void *in;int err;int i; - current_headroom_size = port_buffer->headroom_size; - in =kzalloc (sz,GFP_KERNEL );if (!in)return -ENOMEM ;
@@ -306,12 +304,14 @@ static int port_set_buffer(struct mlx5e_priv *priv,for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) {void *buffer =MLX5_ADDR_OF (pbmc_reg, in, buffer[i]); + current_headroom_cells +=MLX5_GET (bufferx_reg, buffer, size); +u64 size = port_buffer->buffer[i].size;u64 xoff = port_buffer->buffer[i].xoff;u64 xon = port_buffer->buffer[i].xon; - new_headroom_size += size;do_div (size, port_buff_cell_sz); + new_headroom_cells += size;do_div (xoff, port_buff_cell_sz);do_div (xon, port_buff_cell_sz);MLX5_SET (bufferx_reg, buffer, size, size);
@@ -320,10 +320,8 @@ static int port_set_buffer(struct mlx5e_priv *priv,MLX5_SET (bufferx_reg, buffer, xon_threshold, xon); } - new_headroom_size /= port_buff_cell_sz; - current_headroom_size /= port_buff_cell_sz; - err =port_update_shared_buffer (priv->mdev, current_headroom_size, - new_headroom_size); + err =port_update_shared_buffer (priv->mdev, current_headroom_cells, + new_headroom_cells);if (err) goto out;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 452/457 ALSA: usb-audio: Use correct sub-type for UAC3 feature unit validation
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 8410fe81093ff231e964891e215b624dabb734b0 ]
The entry of the validators table for UAC3 feature unit is defined with a wrong sub-type UAC_FEATURE (= 0x06) while it should have been UAC3_FEATURE (= 0x07). This patch corrects the entry value.
--- sound/usb/validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/validate.c +1 -1
@@ -285,7 +285,7 @@ static const struct usb_desc_validator audio_validators[] = {/* UAC_VERSION_3, UAC3_EXTENDED_TERMINAL: not implemented yet */ FUNC (UAC_VERSION_3 ,UAC3_MIXER_UNIT , validate_mixer_unit),FUNC (UAC_VERSION_3 ,UAC3_SELECTOR_UNIT , validate_selector_unit), -FUNC (UAC_VERSION_3 ,UAC_FEATURE_UNIT , validate_uac3_feature_unit), +FUNC (UAC_VERSION_3 ,UAC3_FEATURE_UNIT , validate_uac3_feature_unit),/* UAC_VERSION_3, UAC3_EFFECT_UNIT: not implemented yet */ FUNC (UAC_VERSION_3 ,UAC3_PROCESSING_UNIT , validate_processing_unit), FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNIT, validate_processing_unit),
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 453/457 s390/hypfs: Avoid unnecessary ioctl registration in debugfs
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
[ Upstream commit fec7bdfe7f8694a0c39e6c3ec026ff61ca1058b9 ]
Currently, hypfs registers ioctl callbacks for all debugfs files, despite only one file requiring them. This leads to unintended exposure of unused interfaces to user space and can trigger side effects such as restricted access when kernel lockdown is enabled.
Restrict ioctl registration to only those files that implement ioctl functionality to avoid interface clutter and unnecessary access restrictions.
--- arch/s390/hypfs/hypfs_dbfs.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
arch/s390/hypfs/hypfs_dbfs.c +11 -7
@@ -66,23 +66,27 @@ static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)long rc;mutex_lock (&df->lock); -if (df->unlocked_ioctl) - rc = df->unlocked_ioctl (file, cmd, arg); -else - rc = -ENOTTY ; + rc = df->unlocked_ioctl (file, cmd, arg);mutex_unlock (&df->lock);return rc; } -static const struct file_operations dbfs_ops = { +static const struct file_operations dbfs_ops_ioctl = { .read = dbfs_read, .unlocked_ioctl = dbfs_ioctl, }; +static const struct file_operations dbfs_ops = { + .read = dbfs_read, +}; +void hypfs_dbfs_create_file (struct hypfs_dbfs_file *df) { - df->dentry =debugfs_create_file (df->name,0400 , dbfs_dir, df, - &dbfs_ops); +const struct file_operations *fops = &dbfs_ops; + +if (df->unlocked_ioctl) + fops = &dbfs_ops_ioctl; + df->dentry =debugfs_create_file (df->name,0400 , dbfs_dir, df, fops);mutex_init (&df->lock); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 454/457 s390/hypfs: Enable limited access during lockdown
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
[ Upstream commit 3868f910440c47cd5d158776be4ba4e2186beda7 ]
When kernel lockdown is active, debugfs_locked_down() blocks access to hypfs files that register ioctl callbacks, even if the ioctl interface is not required for a function. This unnecessarily breaks userspace tools that only rely on read operations.
Resolve this by registering a minimal set of file operations during lockdown, avoiding ioctl registration and preserving access for affected tooling.
Note that this change restores hypfs functionality when lockdown is active from early boot (e.g. via lockdown=integrity kernel parameter), but does not apply to scenarios where lockdown is enabled dynamically while Linux is running.
--- arch/s390/hypfs/hypfs_dbfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/s390/hypfs/hypfs_dbfs.c +2 -1
@@ -6,6 +6,7 @@* Author(s): Michael Holzheu <[email protected]> */ +#include <linux/security.h> #include <linux/slab.h> #include "hypfs.h"
@@ -84,7 +85,7 @@ void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) {const struct file_operations *fops = &dbfs_ops; -if (df->unlocked_ioctl) +if (df->unlocked_ioctl && !security_locked_down (LOCKDOWN_DEBUGFS )) fops = &dbfs_ops_ioctl; df->dentry =debugfs_create_file (df->name,0400 , dbfs_dir, df, fops);mutex_init (&df->lock);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 455/457 netfilter: nf_reject: dont leak dst refcount for loopback packets
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit 91a79b792204313153e1bdbbe5acbfc28903b3a5 ]
recent patches to add a WARN() when replacing skb dst entry found an old bug:
WARNING: include/linux/skbuff.h:1165 skb_dst_check_unset include/linux/skbuff.h:1164 [inline] WARNING: include/linux/skbuff.h:1165 skb_dst_set include/linux/skbuff.h:1210 [inline] WARNING: include/linux/skbuff.h:1165 nf_reject_fill_skb_dst+0x2a4/0x330 net/ipv4/netfilter/nf_reject_ipv4.c:234 [..] Call Trace: nf_send_unreach+0x17b/0x6e0 net/ipv4/netfilter/nf_reject_ipv4.c:325 nft_reject_inet_eval+0x4bc/0x690 net/netfilter/nft_reject_inet.c:27 expr_call_ops_eval net/netfilter/nf_tables_core.c:237 [inline] ..
This is because blamed commit forgot about loopback packets. Such packets already have a dst_entry attached, even at PRE_ROUTING stage.
Instead of checking hook just check if the skb already has a route attached to it.
--- net/ipv4/netfilter/nf_reject_ipv4.c | 6 ++---- net/ipv6/netfilter/nf_reject_ipv6.c | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-)
net/ipv4/netfilter/nf_reject_ipv4.c +2 -4
@@ -247,8 +247,7 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,if (!oth)return ; -if ((hook ==NF_INET_PRE_ROUTING || hook ==NF_INET_INGRESS ) && -nf_reject_fill_skb_dst (oldskb) <0 ) +if (!skb_dst (oldskb) &&nf_reject_fill_skb_dst (oldskb) <0 )return ;if (skb_rtable (oldskb)->rt_flags & (RTCF_BROADCAST |RTCF_MULTICAST ))
@@ -321,8 +320,7 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)if (iph->frag_off &htons (IP_OFFSET ))return ; -if ((hook ==NF_INET_PRE_ROUTING || hook ==NF_INET_INGRESS ) && -nf_reject_fill_skb_dst (skb_in) <0 ) +if (!skb_dst (skb_in) &&nf_reject_fill_skb_dst (skb_in) <0 )return ; if (skb_csum_unnecessary(skb_in) ||
net/ipv6/netfilter/nf_reject_ipv6.c +2 -3
@@ -293,7 +293,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb, fl6.fl6_sport = otcph->dest; fl6.fl6_dport = otcph->source; -if (hook ==NF_INET_PRE_ROUTING || hook ==NF_INET_INGRESS ) { +if (!skb_dst (oldskb)) {nf_ip6_route (net, &dst,flowi6_to_flowi (&fl6), false);if (!dst)return ;
@@ -397,8 +397,7 @@ void nf_send_unreach6(struct net *net, struct sk_buff *skb_in,if (hooknum ==NF_INET_LOCAL_OUT && skb_in->dev ==NULL ) skb_in->dev = net->loopback_dev; -if ((hooknum ==NF_INET_PRE_ROUTING || hooknum ==NF_INET_INGRESS ) && -nf_reject6_fill_skb_dst (skb_in) <0 ) +if (!skb_dst (skb_in) &&nf_reject6_fill_skb_dst (skb_in) <0 )return ;icmpv6_send (skb_in,ICMPV6_DEST_UNREACH , code,0 );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 456/457 drm/xe: Move ASID allocation and user PT BO tracking into xe_vm_create
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Piotr Piórkowski <[email protected]>
[ Upstream commit 8a30114073639fd97f2c7390abbc34fb8711327a ]
Currently, ASID assignment for user VMs and page-table BO accounting for client memory tracking are performed in xe_vm_create_ioctl. To consolidate VM object initialization, move this logic to xe_vm_create.
v2:
- removed unnecessary duplicate BO tracking code
- using the local variable xef to verify whether the VM is being created by userspace
--- drivers/gpu/drm/xe/xe_vm.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-)
drivers/gpu/drm/xe/xe_vm.c +15 -19
@@ -1767,6 +1767,20 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct xe_file *xef)if (number_tiles >1 ) vm->composite_fence_ctx =dma_fence_context_alloc (1 ); +if (xef && xe->info.has_asid) { +u32 asid; + +down_write (&xe->usm.lock); + err =xa_alloc_cyclic (&xe->usm.asid_to_vm, &asid, vm, +XA_LIMIT (1 ,XE_MAX_ASID -1 ), + &xe->usm.next_asid,GFP_KERNEL ); +up_write (&xe->usm.lock); +if (err <0 ) + goto err_unlock_close; + + vm->usm.asid = asid; + } +trace_xe_vm_create (vm);return vm;
@@ -2034,9 +2048,8 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,struct xe_device *xe =to_xe_device (dev);struct xe_file *xef =to_xe_file (file);struct drm_xe_vm_create *args = data; -struct xe_tile *tile;struct xe_vm *vm; -u32 id, asid; +u32 id;int err;u32 flags =0 ;
@@ -2076,23 +2089,6 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,if (IS_ERR (vm))return PTR_ERR (vm); -if (xe->info.has_asid) { -down_write (&xe->usm.lock); - err =xa_alloc_cyclic (&xe->usm.asid_to_vm, &asid, vm, -XA_LIMIT (1 ,XE_MAX_ASID -1 ), - &xe->usm.next_asid,GFP_KERNEL ); -up_write (&xe->usm.lock); -if (err <0 ) - goto err_close_and_put; - - vm->usm.asid = asid; - } - -/* Record BO memory for VM pagetable created against client */ -for_each_tile (tile, xe, id) -if (vm->pt_root[id]) -xe_drm_client_add_bo (vm->xef->client, vm->pt_root[id]->bo); -#if IS_ENABLED (CONFIG_DRM_XE_DEBUG_MEM )/* Warning: Security issue - never enable by default */ args->reserved[0 ] =xe_bo_main_addr (vm->pt_root[0 ]->bo,XE_PAGE_SIZE );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 457/457 drm/xe: Fix vm_bind_ioctl double free bug
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Manszewski <[email protected]>
[ Upstream commit 111fb43a557726079a67ce3ab51f602ddbf7097e ]
If the argument check during an array bind fails, the bind_ops are freed twice as seen below. Fix this by setting bind_ops to NULL after freeing.
==================================================================
BUG: KASAN: double-free in xe_vm_bind_ioctl+0x1b2/0x21f0 [xe]
Free of addr ffff88813bb9b800 by task xe_vm/14198
CPU: 5 UID: 0 PID: 14198 Comm: xe_vm Not tainted 6.16.0-xe-eudebug-cmanszew+ #520 PREEMPT(full) Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR5 RVP, BIOS ADLPFWI1.R00.2411.A02.2110081023 10/08/2021 Call Trace: <TASK> dump_stack_lvl+0x82/0xd0 print_report+0xcb/0x610 ? __virt_addr_valid+0x19a/0x300 ? xe_vm_bind_ioctl+0x1b2/0x21f0 [xe] kasan_report_invalid_free+0xc8/0xf0 ? xe_vm_bind_ioctl+0x1b2/0x21f0 [xe] ? xe_vm_bind_ioctl+0x1b2/0x21f0 [xe] check_slab_allocation+0x102/0x130 kfree+0x10d/0x440 ? should_fail_ex+0x57/0x2f0 ? xe_vm_bind_ioctl+0x1b2/0x21f0 [xe] xe_vm_bind_ioctl+0x1b2/0x21f0 [xe] ? __pfx_xe_vm_bind_ioctl+0x10/0x10 [xe] ? __lock_acquire+0xab9/0x27f0 ? lock_acquire+0x165/0x300 ? drm_dev_enter+0x53/0xe0 [drm] ? find_held_lock+0x2b/0x80 ? drm_dev_exit+0x30/0x50 [drm] ? drm_ioctl_kernel+0x128/0x1c0 [drm] drm_ioctl_kernel+0x128/0x1c0 [drm] ? __pfx_xe_vm_bind_ioctl+0x10/0x10 [xe] ? find_held_lock+0x2b/0x80 ? __pfx_drm_ioctl_kernel+0x10/0x10 [drm] ? should_fail_ex+0x57/0x2f0 ? __pfx_xe_vm_bind_ioctl+0x10/0x10 [xe] drm_ioctl+0x352/0x620 [drm] ? __pfx_drm_ioctl+0x10/0x10 [drm] ? __pfx_rpm_resume+0x10/0x10 ? do_raw_spin_lock+0x11a/0x1b0 ? find_held_lock+0x2b/0x80 ? __pm_runtime_resume+0x61/0xc0 ? rcu_is_watching+0x20/0x50 ? trace_irq_enable.constprop.0+0xac/0xe0 xe_drm_ioctl+0x91/0xc0 [xe] __x64_sys_ioctl+0xb2/0x100 ? rcu_is_watching+0x20/0x50 do_syscall_64+0x68/0x2e0 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fa9acb24ded
--- drivers/gpu/drm/xe/xe_vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/xe/xe_vm.c +2 -1
@@ -3200,6 +3200,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, free_bind_ops:if (args->num_binds >1 )kvfree (*bind_ops); + *bind_ops =NULL ;return err; }
@@ -3305,7 +3306,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)struct xe_exec_queue *q =NULL ;u32 num_syncs, num_ufence =0 ;struct xe_sync_entry *syncs =NULL ; -struct drm_xe_vm_bind_op *bind_ops; +struct drm_xe_vm_bind_op *bind_ops =NULL ;struct xe_vma_ops vops;struct dma_fence *fence;int err;
Signature · 1 line
2.50.1
Hi Greg
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
6.16.4-rc1 tested.
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
[ 0.000000] Linux version 6.16.4-rc1rv-g2894c4c9dabd
(takeshi@ThinkPadX1Gen10J0764) (gcc (GCC) 15.2.1 20250813, GNU ld (GNU Binutils) 2.45.0) #1 SMP PREEMPT_DYNAMIC Tue Aug 26 21:54:15 JST 2025
Thanks
Quoted 8 lines · On Tue, 26 Aug 2025 13:04:44 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested for loongarch64:
(By the way, this one builds cleanly for arm 32-bit too -- I normally don't report on it since it is not clean, but it is nice to see it may be getting there).
Thanks!
Cheers,
Miguel
[2025-08-26 13:04] Greg Kroah-Hartman:
Quoted 5 lines
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.
Hi Greg, 6.16.4-rc1 (6.16.3 + all patches from the stable queue from 24h ago) compiles fine for x86_64 using GCC 15.2.1+r22+gc4e96a094636 and binutils 2.45+r29+g2b2e51a31ec7, and the resulting kernel has been running without any discernible issues since roughly 00:00 UTC today on various physical machines of mine (Ivy Bridge, Haswell, Kaby Lake, Coffee Lake) and in a Zen 2 VM and a bunch of Kaby Lake VMs.
Regards
Pascal
Pascal Ernster
Tested-by[2025-08-26 17:10] Pascal Ernster:
Quoted 16 lines
[2025-08-26 13:04] Greg Kroah-Hartman:
Quoted 5 lines
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.
Quoted 5 lines
Hi Greg, 6.16.4-rc1 (6.16.3 + all patches from the stable queue from 24h ago) compiles fine for
x86_64using GCC 15.2.1+r22+gc4e96a094636 and binutils 2.45+r29+g2b2e51a31ec7, and the resulting kernel has been running without any discernible issues since roughly 00:00 UTC today on various physical machines of mine (Ivy Bridge, Haswell, Kaby Lake, Coffee Lake) and in a Zen 2 VM and a bunch of Kaby Lake VMs.Regards
Pascal
Hi
no regressions here on x86_64 (RKL, Intel 11th Gen. CPU)
Thanks
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
Build and boot tested 6.16.4-rc1 using qemu-x86_64. The kernel was successfully built and booted in a virtualized environment without issues.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
Tested rc1 against the Fedora build system (aarch64, ppc64le, s390x, x86_64), and boot tested x86_64. No regressions noted.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.16:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
120 tests: 120 pass, 0 failLinux version: 6.16.4-rc1-g2894c4c9dabd
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
# Librecast Test Results
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.16.4-rc1-g2894c4c9dabd #52 SMP PREEMPT_DYNAMIC Tue Aug 26 17:28:33 -00 2025 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
Thanks! Builded on all Alpine architectures (aarch64, armv7, loongarch64, ppc64le, riscv64, s390x, x86, x86_64) and boot-tested on x86_64.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Am 26.08.2025 um 13:04 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 6.16.4-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: 2894c4c9dabd275ab1a7338d9631bc10e5649c91
* git describe: v6.16.3-458-g2894c4c9dabd
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.16.y/build/v6.16.3-458-g2894c4c9dabd
## Test Regressions (compared to v6.16.2-10-g3fb8628191b4)
## Metric Regressions (compared to v6.16.2-10-g3fb8628191b4)
## Test Fixes (compared to v6.16.2-10-g3fb8628191b4)
## Metric Fixes (compared to v6.16.2-10-g3fb8628191b4)
## Test result summary
total: 344576, pass: 317202, fail: 7069, skip: 20305, xfail: 0
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 139 total, 138 passed, 1 failed
* arm64: 57 total, 56 passed, 1 failed
* i386: 18 total, 18 passed, 0 failed
* mips: 34 total, 27 passed, 7 failed
* parisc: 4 total, 4 passed, 0 failed
* powerpc: 40 total, 39 passed, 1 failed
* riscv: 25 total, 24 passed, 1 failed
* s390: 22 total, 22 passed, 0 failed
* sh: 5 total, 5 passed, 0 failed
* sparc: 4 total, 3 passed, 1 failed
* x86_64: 49 total, 48 passed, 1 failed
## Test suites summary
* boot
* commands
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-efivarfs
* kselftest-exec
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-kcmp
* kselftest-kvm
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-mincore
* kselftest-mm
* kselftest-mqueue
* kselftest-net
* kselftest-net-mptcp
* kselftest-openat2
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-rust
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-tc-testing
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user_events
* kselftest-vDSO
* kselftest-x86
* kunit
* kvm-unit-tests
* lava
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-build-clang
* log-parser-build-gcc
* log-parser-test
* ltp-capability
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-hugetlb
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-pty
* ltp-sched
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* modules
* perf
* rcutorture
* rt-tests-cyclicdeadline
* rt-tests-pi-stress
* rt-tests-pmqtest
* rt-tests-rt-migrate-test
* rt-tests-signaltest
--
Linaro LKFT
https://lkft.linaro.org
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.4-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.16.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 28 Aug 2025 11:08:27 +0000. Anything received after that time might be too late.
Tested on the following hardware:
* a ThinkPad E14 Gen 3 with a AMD Ryzen 5 5500U CPU
* a Framework Laptop with a Ryzen AI 5 340
* a Framework Desktop
* a Steam Deck (LCD Edition)
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.16.4 release. There are 457 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.16.y
6.6, 6.15, 5.15 pass our testing, too:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.15.y
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.6.y
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.15.y
Best regards,
Pavel
Signature · 2 lines
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany