* [syzbot] [bridge?] WARNING: locking bug in match_held_lock @ 2026-09-13 1:31 syzbot 2026-09-15 3:40 ` Shin'ichiro Kawasaki 0 siblings, 1 reply; 7+ messages in thread From: syzbot @ 2026-09-13 1:31 UTC (permalink / raw) To: bridge, davem, edumazet, herbert, horms, idosch, kuba, linux-kernel, netdev, pabeni, razor, steffen.klassert, syzkaller-bugs Hello, syzbot found the following issue on: HEAD commit: a9d7ced84989 Add linux-next specific files for 20260908 git tree: linux-next console output: https://syzkaller.appspot.com/x/log.txt?x=10880f49580000 kernel config: https://syzkaller.appspot.com/x/.config?x=17eeb09695a2b3c9 dashboard link: https://syzkaller.appspot.com/bug?extid=4d0e4d2db6dfde01b52f compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8 Unfortunately, I don't have any reproducer for this issue yet. Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/4f470407358e/disk-a9d7ced8.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/858b9d7ba687/vmlinux-a9d7ced8.xz kernel image: https://storage.googleapis.com/syzbot-assets/ef971d22d75f/bzImage-a9d7ced8.xz IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com ------------[ cut here ]------------ Looking for class "&ht->mutex" with key xfrm_policy_init.__key.84, but found a different class "key" with the same key WARNING: kernel/locking/lockdep.c:958 at look_up_lock_class+0x8c/0x110 kernel/locking/lockdep.c:955, CPU#1: kworker/1:6/5751 Modules linked in: CPU: 1 UID: 0 PID: 5751 Comm: kworker/1:6 Tainted: G L syzkaller #0 PREEMPT(full) Tainted: [L]=SOFTLOCKUP Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026 Workqueue: usb_hub_wq hub_event RIP: 0010:look_up_lock_class+0x9a/0x110 kernel/locking/lockdep.c:955 Code: 00 00 49 3b 46 18 0f 84 82 00 00 00 49 81 3e d0 44 58 94 74 79 48 8d 3d 44 f2 94 04 49 8b 16 49 8b 76 18 48 8b 8b b8 00 00 00 <67> 48 0f b9 3a eb 5d 90 89 f3 e8 67 0a f4 f8 e8 32 5c be f5 48 c7 RSP: 0018:ffffc90000a38070 EFLAGS: 00010002 RAX: ffffffff8c6bb940 RBX: ffffffff94478508 RCX: ffffffff8c6bb940 RDX: ffffffff9af23440 RSI: ffffffff8c6bb900 RDI: ffffffff907ddb20 RBP: 00000000ffffffff R08: 0000000000000100 R09: 0000000000000004 R10: 0000000000000003 R11: 0000000000000300 R12: 0000000000000246 R13: ffff8880307a8000 R14: ffffffff9af232c8 R15: ffffffff9af23440 FS: 0000000000000000(0000) GS:ffff888124db7000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b3401aff8 CR3: 0000000074540000 CR4: 00000000003526f0 Call Trace: <IRQ> match_held_lock+0x9a/0x120 kernel/locking/lockdep.c:5364 __lock_is_held kernel/locking/lockdep.c:5654 [inline] lock_is_held_type+0x89/0x150 kernel/locking/lockdep.c:6016 __rhashtable_lookup include/linux/rhashtable.h:623 [inline] rhashtable_lookup include/linux/rhashtable.h:668 [inline] xfrm_policy_inexact_lookup_rcu+0x60/0x750 net/xfrm/xfrm_policy.c:2068 xfrm_policy_lookup_bytype+0xb35/0x1840 net/xfrm/xfrm_policy.c:2193 xfrm_policy_lookup net/xfrm/xfrm_policy.c:2225 [inline] xfrm_bundle_lookup net/xfrm/xfrm_policy.c:3100 [inline] xfrm_lookup_with_ifid+0x416/0x1db0 net/xfrm/xfrm_policy.c:3241 xfrmi_xmit2 net/xfrm/xfrm_interface_core.c:456 [inline] xfrmi_xmit+0x72d/0x1b80 net/xfrm/xfrm_interface_core.c:572 __netdev_start_xmit include/linux/netdevice.h:5433 [inline] netdev_start_xmit include/linux/netdevice.h:5442 [inline] xmit_one net/core/dev.c:3937 [inline] dev_hard_start_xmit+0x2cd/0x830 net/core/dev.c:3953 __dev_queue_xmit+0x14c0/0x3820 net/core/dev.c:4926 NF_HOOK_COND include/linux/netfilter.h:314 [inline] ip6_output+0x337/0x540 net/ipv6/ip6_output.c:248 dst_output include/net/dst.h:471 [inline] NF_HOOK include/linux/netfilter.h:325 [inline] ndisc_send_skb+0xcb2/0x1650 net/ipv6/ndisc.c:513 addrconf_rs_timer+0x2d2/0x6c0 net/ipv6/addrconf.c:4078 call_timer_fn+0x18d/0x5f0 kernel/time/timer.c:1748 expire_timers kernel/time/timer.c:1799 [inline] __run_timers kernel/time/timer.c:2374 [inline] __run_timer_base+0x652/0x8b0 kernel/time/timer.c:2386 run_timer_base kernel/time/timer.c:2395 [inline] run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2405 handle_softirqs+0x223/0x840 kernel/softirq.c:645 __do_softirq kernel/softirq.c:679 [inline] invoke_softirq kernel/softirq.c:519 [inline] __irq_exit_rcu+0xcb/0x220 kernel/softirq.c:758 irq_exit_rcu+0x9/0x30 kernel/softirq.c:775 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062 [inline] sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1062 </IRQ> <TASK> asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:674 RIP: 0010:finish_task_switch+0x413/0xc60 kernel/sched/core.c:5378 Code: 04 00 00 41 c7 84 24 20 0e 00 00 00 00 00 00 0f 1f 44 00 00 49 83 c4 48 4c 89 e7 e8 57 48 55 0a e8 d2 1b 3a 00 fb 4c 8b 65 c8 <49> 8d bc 24 10 17 00 00 48 89 f8 48 c1 e8 03 42 0f b6 04 30 84 c0 RSP: 0018:ffffc900043ad940 EFLAGS: 00000206 RAX: 000000000004ba5f RBX: ffff8880b873cb20 RCX: 8000000000000001 RDX: 0000000000000006 RSI: ffffffff8e47d8da RDI: ffffffff8c6dc080 RBP: ffffc900043ad990 R08: ffffffff907a9cbf R09: 1ffffffff20f5397 R10: dffffc0000000000 R11: fffffbfff20f5398 R12: ffff8880307a8000 R13: ffff8880b873cae8 R14: dffffc0000000000 R15: 1ffff110170e7964 context_switch kernel/sched/core.c:5530 [inline] __schedule+0x17e5/0x5940 kernel/sched/core.c:7295 preempt_schedule_common+0x7f/0xd0 kernel/sched/core.c:7474 preempt_schedule_thunk+0x16/0x40 arch/x86/entry/thunk.S:12 __mutex_lock_common kernel/locking/mutex.c:656 [inline] __mutex_lock+0x31b/0x15a0 kernel/locking/mutex.c:821 clear_eld drivers/gpu/drm/drm_edid.c:5691 [inline] update_display_info+0x455/0x9630 drivers/gpu/drm/drm_edid.c:6934 drm_edid_connector_update+0x9b/0x13d0 drivers/gpu/drm/drm_edid.c:7338 drm_connector_update_edid_property+0xde/0x140 drivers/gpu/drm/drm_edid.c:7396 drm_helper_probe_single_connector_modes+0x126b/0x1880 drivers/gpu/drm/drm_probe_helper.c:644 drm_client_modeset_probe+0x4e8/0x60c0 drivers/gpu/drm/drm_client_modeset.c:869 __drm_fb_helper_initial_config_and_unlock+0x10e/0x1b50 drivers/gpu/drm/drm_fb_helper.c:1717 drm_fbdev_client_hotplug+0x16c/0x230 drivers/gpu/drm/clients/drm_fbdev_client.c:66 drm_client_register+0x16e/0x200 drivers/gpu/drm/drm_client.c:143 drm_fbdev_client_setup+0x1a0/0x450 drivers/gpu/drm/clients/drm_fbdev_client.c:168 drm_client_setup+0x107/0x220 drivers/gpu/drm/clients/drm_client_setup.c:46 udl_usb_probe+0x137/0x150 drivers/gpu/drm/udl/udl_drv.c:105 usb_probe_interface+0x788/0xe50 drivers/usb/core/driver.c:399 call_driver_probe drivers/base/dd.c:-1 [inline] really_probe+0x254/0xae0 drivers/base/dd.c:706 __driver_probe_device+0x1e8/0x360 drivers/base/dd.c:868 driver_probe_device+0x4f/0x240 drivers/base/dd.c:898 __device_attach_driver+0x270/0x410 drivers/base/dd.c:1026 bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500 __device_attach+0x2c4/0x450 drivers/base/dd.c:1098 device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1153 bus_probe_device+0x12a/0x220 drivers/base/bus.c:620 device_add+0x7d7/0xb80 drivers/base/core.c:3776 usb_set_configuration+0x1ad8/0x2180 drivers/usb/core/message.c:2268 usb_generic_driver_probe+0x8d/0x150 drivers/usb/core/generic.c:250 usb_probe_device+0x1c3/0x3b0 drivers/usb/core/driver.c:293 call_driver_probe drivers/base/dd.c:-1 [inline] really_probe+0x254/0xae0 drivers/base/dd.c:706 __driver_probe_device+0x1e8/0x360 drivers/base/dd.c:868 driver_probe_device+0x4f/0x240 drivers/base/dd.c:898 __device_attach_driver+0x270/0x410 drivers/base/dd.c:1026 bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500 __device_attach+0x2c4/0x450 drivers/base/dd.c:1098 device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1153 bus_probe_device+0x12a/0x220 drivers/base/bus.c:620 device_add+0x7d7/0xb80 drivers/base/core.c:3776 usb_new_device+0x9aa/0x1690 drivers/usb/core/hub.c:2708 hub_port_connect drivers/usb/core/hub.c:5580 [inline] hub_port_connect_change drivers/usb/core/hub.c:5720 [inline] port_event drivers/usb/core/hub.c:5884 [inline] hub_event+0x28e8/0x4d30 drivers/usb/core/hub.c:5966 process_one_work kernel/workqueue.c:3407 [inline] process_scheduled_works+0xc3d/0x1630 kernel/workqueue.c:3490 worker_thread+0xa47/0xfb0 kernel/workqueue.c:3571 kthread+0x38b/0x480 kernel/kthread.c:436 ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK> ---------------- Code disassembly (best guess): 0: 00 00 add %al,(%rax) 2: 49 3b 46 18 cmp 0x18(%r14),%rax 6: 0f 84 82 00 00 00 je 0x8e c: 49 81 3e d0 44 58 94 cmpq $0xffffffff945844d0,(%r14) 13: 74 79 je 0x8e 15: 48 8d 3d 44 f2 94 04 lea 0x494f244(%rip),%rdi # 0x494f260 1c: 49 8b 16 mov (%r14),%rdx 1f: 49 8b 76 18 mov 0x18(%r14),%rsi 23: 48 8b 8b b8 00 00 00 mov 0xb8(%rbx),%rcx * 2a: 67 48 0f b9 3a ud1 (%edx),%rdi <-- trapping instruction 2f: eb 5d jmp 0x8e 31: 90 nop 32: 89 f3 mov %esi,%ebx 34: e8 67 0a f4 f8 call 0xf8f40aa0 39: e8 32 5c be f5 call 0xf5be5c70 3e: 48 rex.W 3f: c7 .byte 0xc7 --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkaller@googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. If the report is already addressed, let syzbot know by replying with: #syz fix: exact-commit-title If you want to overwrite report's subsystems, reply with: #syz set subsystems: new-subsystem (See the list of subsystem names on the web dashboard) If the report is a duplicate of another one, reply with: #syz dup: exact-subject-of-another-report If you want to undo deduplication, reply with: #syz undup ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [syzbot] [bridge?] WARNING: locking bug in match_held_lock 2026-09-13 1:31 [syzbot] [bridge?] WARNING: locking bug in match_held_lock syzbot @ 2026-09-15 3:40 ` Shin'ichiro Kawasaki 2026-09-15 4:06 ` Eric Dumazet 0 siblings, 1 reply; 7+ messages in thread From: Shin'ichiro Kawasaki @ 2026-09-15 3:40 UTC (permalink / raw) To: syzbot Cc: bridge, davem, edumazet, herbert, horms, idosch, kuba, linux-kernel, netdev, pabeni, razor, steffen.klassert, syzkaller-bugs, Thomas Graf, linux-crypto CC+: linux-crypto and rhashtable maintainers, On Sep 12, 2026 / 18:31, syzbot wrote: > Hello, > > syzbot found the following issue on: > > HEAD commit: a9d7ced84989 Add linux-next specific files for 20260908 > git tree: linux-next > console output: https://syzkaller.appspot.com/x/log.txt?x=10880f49580000 > kernel config: https://syzkaller.appspot.com/x/.config?x=17eeb09695a2b3c9 > dashboard link: https://syzkaller.appspot.com/bug?extid=4d0e4d2db6dfde01b52f > compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8 > > Unfortunately, I don't have any reproducer for this issue yet. > > Downloadable assets: > disk image: https://storage.googleapis.com/syzbot-assets/4f470407358e/disk-a9d7ced8.raw.xz > vmlinux: https://storage.googleapis.com/syzbot-assets/858b9d7ba687/vmlinux-a9d7ced8.xz > kernel image: https://storage.googleapis.com/syzbot-assets/ef971d22d75f/bzImage-a9d7ced8.xz > > IMPORTANT: if you fix the issue, please add the following tag to the commit: > Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com > > ------------[ cut here ]------------ > Looking for class "&ht->mutex" with key xfrm_policy_init.__key.84, but found a different class "key" with the same key > WARNING: kernel/locking/lockdep.c:958 at look_up_lock_class+0x8c/0x110 kernel/locking/lockdep.c:955, CPU#1: kworker/1:6/5751 > Modules linked in: > CPU: 1 UID: 0 PID: 5751 Comm: kworker/1:6 Tainted: G L syzkaller #0 PREEMPT(full) > Tainted: [L]=SOFTLOCKUP > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026 > Workqueue: usb_hub_wq hub_event > RIP: 0010:look_up_lock_class+0x9a/0x110 kernel/locking/lockdep.c:955 > Code: 00 00 49 3b 46 18 0f 84 82 00 00 00 49 81 3e d0 44 58 94 74 79 48 8d 3d 44 f2 94 04 49 8b 16 49 8b 76 18 48 8b 8b b8 00 00 00 <67> 48 0f b9 3a eb 5d 90 89 f3 e8 67 0a f4 f8 e8 32 5c be f5 48 c7 > RSP: 0018:ffffc90000a38070 EFLAGS: 00010002 > RAX: ffffffff8c6bb940 RBX: ffffffff94478508 RCX: ffffffff8c6bb940 > RDX: ffffffff9af23440 RSI: ffffffff8c6bb900 RDI: ffffffff907ddb20 > RBP: 00000000ffffffff R08: 0000000000000100 R09: 0000000000000004 > R10: 0000000000000003 R11: 0000000000000300 R12: 0000000000000246 > R13: ffff8880307a8000 R14: ffffffff9af232c8 R15: ffffffff9af23440 > FS: 0000000000000000(0000) GS:ffff888124db7000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 0000001b3401aff8 CR3: 0000000074540000 CR4: 00000000003526f0 > Call Trace: > <IRQ> > match_held_lock+0x9a/0x120 kernel/locking/lockdep.c:5364 > __lock_is_held kernel/locking/lockdep.c:5654 [inline] > lock_is_held_type+0x89/0x150 kernel/locking/lockdep.c:6016 > __rhashtable_lookup include/linux/rhashtable.h:623 [inline] > rhashtable_lookup include/linux/rhashtable.h:668 [inline] > xfrm_policy_inexact_lookup_rcu+0x60/0x750 net/xfrm/xfrm_policy.c:2068 > xfrm_policy_lookup_bytype+0xb35/0x1840 net/xfrm/xfrm_policy.c:2193 ... FYI, I also observed the WARN at look_up_lock_class() and match_held_lock() called in the rhashtable_lookup() context [1]. I used the kernel next-20260909. The WARN was observed during the run of blktests test case block/008 on dm- flakey device, but this test workload does not look related to the WARN. I tried to reproduce the WARN by repeating the test workload hundreds of times, and succeeded only once. The WARN looks rare, but I'm sure the WARN happned. The call trace that syzbot reported and that I observed look rather different. The common part across them is the rhashtable_lookup() call. So I think it is the better to involve rhashtable experts. I took the liberty CC to them. [1] WARN observed at blktests block/008 for dm-flakey WARNING: kernel/locking/lockdep.c:955 at look_up_lock_class+0xa8/0x170, CPU#14: kworker/14:1/309662 Modules linked in: dm_flakey iscsi_target_mod tcm_loop target_core_pscsi target_core_file target_core_iblock xfs target_core_user target_core_mod nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject qrtr nft_ct nft_chain_nat ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_mangle rfkill iptable_raw iptable_security nf_tables ip6table_filter ip6_tables iptable_filter ip_tables irdma ice sunrpc libie_fwlog gnss idpf libeth_xdp libie_pci libie_cp libeth ib_core intel_rapl_msr intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common skx_edac skx_edac_common nfit libnvdimm x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel spi_nor mtd kvm i40e irqbypass iTCO_wdt rapl intel_pmc_bxt vfat ses intel_cstate libie fat intel_uncore libie_adminq enclosure i2c_i801 spi_intel_pci spi_intel i2c_smbus lpc_ich mei_me mei intel_pch_thermal wmi joydev ioatdma acpi_pad acpi_power_meter dca fuse dm_multipath zram lz4hc_compress zstd_compress ast drm_client_lib i2c_algo_bit drm_shmem_helper drm_kms_helper nvme drm nvme_core mpi3mr nvme_keyring nvme_auth scsi_transport_sas scsi_dh_alua pkcs8_key_parser scsi_dh_emc scsi_dh_rdac i2c_dev [last unloaded: null_blk] CPU: 14 UID: 0 PID: 309662 Comm: kworker/14:1 Tainted: G W 7.3.0-rc2-next-20260909-kts+ #1 PREEMPT(lazy) Tainted: [W]=WARN Hardware name: Supermicro Super Server/X11SPi-TF, BIOS 3.5 05/18/2021 Workqueue: events drm_fb_helper_damage_work [drm_kms_helper] RIP: 0010:look_up_lock_class+0xa8/0x170 Code: 39 6b 40 75 ed 48 8b 8b b8 00 00 00 49 8b 74 24 18 48 39 f1 74 34 49 8b 14 24 48 81 fa f0 31 7f 9a 74 27 48 8d 3d b8 66 4a 02 <67> 48 0f b9 3a 48 89 d8 48 8b 6c 24 10 4c 8b 64 24 18 48 8b 5c 24 RSP: 0018:ffff888e40108088 EFLAGS: 00010002 RAX: 0000000000000001 RBX: ffffffff9e852a78 RCX: ffffffff97838ae0 RDX: ffffffffc271a2a0 RSI: ffffffff97838a60 RDI: ffffffff997aa470 RBP: ffffffffc271a2a0 R08: 0000000000000001 R09: ffff888133ab3018 R10: 0000000000000004 R11: ffff888e40108360 R12: ffff88812d59e1f8 R13: 0000000000000003 R14: 0000000000000246 R15: 00000000ffffffff FS: 0000000000000000(0000) GS:ffff888ea59d3000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055dba25b8c90 CR3: 00000002a6911004 CR4: 00000000007726f0 PKRU: 55555554 Call Trace: <IRQ> match_held_lock+0xdb/0x130 lock_is_held_type+0xb0/0x180 nft_rhash_lookup+0x541/0x7e0 [nf_tables] ? find_held_lock+0x2b/0x80 ? __lock_release.isra.0+0x69/0x1a0 ? lock_release.part.0+0x1c/0x50 ? __pfx_nft_rhash_lookup+0x10/0x10 [nf_tables] nft_set_do_lookup+0x1ac/0x2a0 [nf_tables] ? fib_lookup_good_nhc+0x104/0x380 nft_lookup_eval+0xcc/0x590 [nf_tables] ? lock_is_held_type+0xb0/0x180 nft_do_chain+0x2a9/0x1680 [nf_tables] ? __lock_acquire+0x690/0xd00 ? __pfx_nft_do_chain+0x10/0x10 [nf_tables] ? lock_acquire.part.0+0xc8/0x240 ? find_held_lock+0x2b/0x80 ? __local_bh_enable_ip+0xb4/0x150 ? ipt_do_table+0xa10/0x11e0 [ip_tables] ? ipt_do_table+0xa15/0x11e0 [ip_tables] nft_do_chain_inet+0xdc/0x4a0 [nf_tables] ? __pfx_nft_do_chain_inet+0x10/0x10 [nf_tables] ? __pfx_ipt_do_table+0x10/0x10 [ip_tables] nf_hook_slow+0xbe/0x210 ? lock_is_held_type+0xb0/0x180 ip_local_deliver+0x2d0/0x4a0 ? __pfx_ip_local_deliver+0x10/0x10 ? __pfx_ip_local_deliver_finish+0x10/0x10 ? ip_rcv_finish_core+0x75b/0x1470 ? lock_is_held_type+0xb0/0x180 ip_list_rcv_finish+0x7f8/0xbb0 ? ip_sublist_rcv+0x106/0x2f0 ? __pfx_ip_list_rcv_finish+0x10/0x10 ? __lock_release.isra.0+0x69/0x1a0 ip_sublist_rcv+0x8b/0x2f0 ? __pfx_ip_sublist_rcv+0x10/0x10 ? __pfx_ip_rcv_finish+0x10/0x10 ? ip_rcv_core+0x619/0xd00 ? kasan_save_stack+0x2f/0x50 ip_list_rcv+0x2dd/0x440 ? asm_common_interrupt+0x26/0x40 ? __pfx_ip_list_rcv+0x10/0x10 ? drm_atomic_helper_commit_planes+0x3bd/0x1040 [drm_kms_helper] ? commit_tail+0x204/0x4b0 [drm_kms_helper] ? __lock_acquire+0x691/0xd00 __netif_receive_skb_list_core+0x6bf/0xa10 ? __pfx___netif_receive_skb_list_core+0x10/0x10 ? lock_acquire.part.0+0xc8/0x240 ? netif_receive_skb_list_internal+0x382/0xc90 ? lock_acquire+0x11a/0x140 netif_receive_skb_list_internal+0x603/0xc90 ? dev_gro_receive+0x1e0/0x15f0 ? __pfx_netif_receive_skb_list_internal+0x10/0x10 ? napi_build_skb+0x55/0x1e0 ? i40e_process_skb_fields+0x4a6/0xea0 [i40e] ? i40e_clean_rx_irq+0x96f/0x2140 [i40e] napi_complete_done+0x1a4/0x900 ? __pfx_napi_complete_done+0x10/0x10 i40e_napi_poll+0x408/0xb70 [i40e] ? __pfx_i40e_napi_poll+0x10/0x10 [i40e] __napi_poll+0x351/0x520 net_rx_action+0x446/0xc30 ? __pfx_net_rx_action+0x10/0x10 ? do_raw_spin_unlock+0x59/0x230 ? lock_release.part.0+0x1c/0x50 ? sched_clock_cpu+0x69/0x630 ? mark_held_locks+0x40/0x70 handle_softirqs+0x1de/0x830 ? __pfx_handle_softirqs+0x10/0x10 ? irqtime_account_irq+0x3e/0x2d0 __irq_exit_rcu+0x164/0x290 irq_exit_rcu+0xe/0x20 common_interrupt+0x85/0xa0 </IRQ> <TASK> asm_common_interrupt+0x26/0x40 RIP: 0010:memcpy_toio+0xa3/0x120 Code: 5c e9 d1 59 9f 01 48 85 db 74 ee 40 f6 c5 01 75 49 48 83 fb 01 76 06 40 f6 c5 02 75 29 48 89 d9 48 89 ef 4c 89 e6 48 c1 e9 02 <f3> a5 f6 c3 02 74 02 66 a5 f6 c3 01 74 01 a4 48 83 c4 18 5b 5d 41 RSP: 0018:ffff88811b3a7538 EFLAGS: 00010206 RAX: 0000000000000000 RBX: 0000000000001000 RCX: 00000000000003f0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [syzbot] [bridge?] WARNING: locking bug in match_held_lock 2026-09-15 3:40 ` Shin'ichiro Kawasaki @ 2026-09-15 4:06 ` Eric Dumazet 2026-09-15 6:04 ` [PATCH] rhashtable: Use separate lockdep keys for each lock Herbert Xu 0 siblings, 1 reply; 7+ messages in thread From: Eric Dumazet @ 2026-09-15 4:06 UTC (permalink / raw) To: Shin'ichiro Kawasaki Cc: syzbot, bridge, davem, herbert, horms, idosch, kuba, linux-kernel, netdev, pabeni, razor, steffen.klassert, syzkaller-bugs, Thomas Graf, linux-crypto On Mon, Sep 14, 2026 at 8:40 PM Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> wrote: > > CC+: linux-crypto and rhashtable maintainers, > > On Sep 12, 2026 / 18:31, syzbot wrote: > > Hello, > > > > syzbot found the following issue on: > > > > HEAD commit: a9d7ced84989 Add linux-next specific files for 20260908 > > git tree: linux-next > > console output: https://syzkaller.appspot.com/x/log.txt?x=10880f49580000 > > kernel config: https://syzkaller.appspot.com/x/.config?x=17eeb09695a2b3c9 > > dashboard link: https://syzkaller.appspot.com/bug?extid=4d0e4d2db6dfde01b52f > > compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8 > > > > Unfortunately, I don't have any reproducer for this issue yet. > > > > Downloadable assets: > > disk image: https://storage.googleapis.com/syzbot-assets/4f470407358e/disk-a9d7ced8.raw.xz > > vmlinux: https://storage.googleapis.com/syzbot-assets/858b9d7ba687/vmlinux-a9d7ced8.xz > > kernel image: https://storage.googleapis.com/syzbot-assets/ef971d22d75f/bzImage-a9d7ced8.xz > > > > IMPORTANT: if you fix the issue, please add the following tag to the commit: > > Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com > > > > ------------[ cut here ]------------ > > Looking for class "&ht->mutex" with key xfrm_policy_init.__key.84, but found a different class "key" with the same key > > WARNING: kernel/locking/lockdep.c:958 at look_up_lock_class+0x8c/0x110 kernel/locking/lockdep.c:955, CPU#1: kworker/1:6/5751 > > Modules linked in: > > CPU: 1 UID: 0 PID: 5751 Comm: kworker/1:6 Tainted: G L syzkaller #0 PREEMPT(full) > > Tainted: [L]=SOFTLOCKUP > > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026 > > Workqueue: usb_hub_wq hub_event > > RIP: 0010:look_up_lock_class+0x9a/0x110 kernel/locking/lockdep.c:955 > > Code: 00 00 49 3b 46 18 0f 84 82 00 00 00 49 81 3e d0 44 58 94 74 79 48 8d 3d 44 f2 94 04 49 8b 16 49 8b 76 18 48 8b 8b b8 00 00 00 <67> 48 0f b9 3a eb 5d 90 89 f3 e8 67 0a f4 f8 e8 32 5c be f5 48 c7 > > RSP: 0018:ffffc90000a38070 EFLAGS: 00010002 > > RAX: ffffffff8c6bb940 RBX: ffffffff94478508 RCX: ffffffff8c6bb940 > > RDX: ffffffff9af23440 RSI: ffffffff8c6bb900 RDI: ffffffff907ddb20 > > RBP: 00000000ffffffff R08: 0000000000000100 R09: 0000000000000004 > > R10: 0000000000000003 R11: 0000000000000300 R12: 0000000000000246 > > R13: ffff8880307a8000 R14: ffffffff9af232c8 R15: ffffffff9af23440 > > FS: 0000000000000000(0000) GS:ffff888124db7000(0000) knlGS:0000000000000000 > > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > > CR2: 0000001b3401aff8 CR3: 0000000074540000 CR4: 00000000003526f0 > > Call Trace: > > <IRQ> > > match_held_lock+0x9a/0x120 kernel/locking/lockdep.c:5364 > > __lock_is_held kernel/locking/lockdep.c:5654 [inline] > > lock_is_held_type+0x89/0x150 kernel/locking/lockdep.c:6016 > > __rhashtable_lookup include/linux/rhashtable.h:623 [inline] > > rhashtable_lookup include/linux/rhashtable.h:668 [inline] > > xfrm_policy_inexact_lookup_rcu+0x60/0x750 net/xfrm/xfrm_policy.c:2068 > > xfrm_policy_lookup_bytype+0xb35/0x1840 net/xfrm/xfrm_policy.c:2193 > ... > > FYI, I also observed the WARN at look_up_lock_class() and match_held_lock() > called in the rhashtable_lookup() context [1]. I used the kernel next-20260909. > The WARN was observed during the run of blktests test case block/008 on dm- > flakey device, but this test workload does not look related to the WARN. I tried > to reproduce the WARN by repeating the test workload hundreds of times, and > succeeded only once. The WARN looks rare, but I'm sure the WARN happned. > > The call trace that syzbot reported and that I observed look rather different. > The common part across them is the rhashtable_lookup() call. So I think it is > the better to involve rhashtable experts. I took the liberty CC to them. > > > [1] WARN observed at blktests block/008 for dm-flakey > > WARNING: kernel/locking/lockdep.c:955 at look_up_lock_class+0xa8/0x170, CPU#14: kworker/14:1/309662 > Modules linked in: dm_flakey iscsi_target_mod tcm_loop target_core_pscsi target_core_file target_core_iblock xfs target_core_user target_core_mod nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject qrtr nft_ct nft_chain_nat ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_mangle rfkill iptable_raw iptable_security nf_tables ip6table_filter ip6_tables iptable_filter ip_tables irdma ice sunrpc libie_fwlog gnss idpf libeth_xdp libie_pci libie_cp libeth ib_core intel_rapl_msr intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common skx_edac skx_edac_common nfit libnvdimm x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel spi_nor mtd kvm i40e irqbypass iTCO_wdt rapl intel_pmc_bxt vfat ses intel_cstate libie fat intel_uncore libie_adminq enclosure i2c_i801 spi_intel_pci spi_intel i2c_smbus lpc_ich mei_me mei intel_pch_thermal wmi joydev ioatdma acpi_pad > acpi_power_meter dca fuse dm_multipath zram lz4hc_compress zstd_compress ast drm_client_lib i2c_algo_bit drm_shmem_helper drm_kms_helper nvme drm nvme_core mpi3mr nvme_keyring nvme_auth scsi_transport_sas scsi_dh_alua pkcs8_key_parser scsi_dh_emc scsi_dh_rdac i2c_dev [last unloaded: null_blk] > CPU: 14 UID: 0 PID: 309662 Comm: kworker/14:1 Tainted: G W 7.3.0-rc2-next-20260909-kts+ #1 PREEMPT(lazy) > Tainted: [W]=WARN > Hardware name: Supermicro Super Server/X11SPi-TF, BIOS 3.5 05/18/2021 > Workqueue: events drm_fb_helper_damage_work [drm_kms_helper] > RIP: 0010:look_up_lock_class+0xa8/0x170 > Code: 39 6b 40 75 ed 48 8b 8b b8 00 00 00 49 8b 74 24 18 48 39 f1 74 34 49 8b 14 24 48 81 fa f0 31 7f 9a 74 27 48 8d 3d b8 66 4a 02 <67> 48 0f b9 3a 48 89 d8 48 8b 6c 24 10 4c 8b 64 24 18 48 8b 5c 24 > RSP: 0018:ffff888e40108088 EFLAGS: 00010002 > RAX: 0000000000000001 RBX: ffffffff9e852a78 RCX: ffffffff97838ae0 > RDX: ffffffffc271a2a0 RSI: ffffffff97838a60 RDI: ffffffff997aa470 > RBP: ffffffffc271a2a0 R08: 0000000000000001 R09: ffff888133ab3018 > R10: 0000000000000004 R11: ffff888e40108360 R12: ffff88812d59e1f8 > R13: 0000000000000003 R14: 0000000000000246 R15: 00000000ffffffff > FS: 0000000000000000(0000) GS:ffff888ea59d3000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 000055dba25b8c90 CR3: 00000002a6911004 CR4: 00000000007726f0 > PKRU: 55555554 > Call Trace: > <IRQ> > match_held_lock+0xdb/0x130 > lock_is_held_type+0xb0/0x180 > nft_rhash_lookup+0x541/0x7e0 [nf_tables] > ? find_held_lock+0x2b/0x80 > ? __lock_release.isra.0+0x69/0x1a0 > ? lock_release.part.0+0x1c/0x50 > ? __pfx_nft_rhash_lookup+0x10/0x10 [nf_tables] > nft_set_do_lookup+0x1ac/0x2a0 [nf_tables] > ? fib_lookup_good_nhc+0x104/0x380 > nft_lookup_eval+0xcc/0x590 [nf_tables] > ? lock_is_held_type+0xb0/0x180 > nft_do_chain+0x2a9/0x1680 [nf_tables] > ? __lock_acquire+0x690/0xd00 > ? __pfx_nft_do_chain+0x10/0x10 [nf_tables] > ? lock_acquire.part.0+0xc8/0x240 > ? find_held_lock+0x2b/0x80 > ? __local_bh_enable_ip+0xb4/0x150 > ? ipt_do_table+0xa10/0x11e0 [ip_tables] > ? ipt_do_table+0xa15/0x11e0 [ip_tables] > nft_do_chain_inet+0xdc/0x4a0 [nf_tables] > ? __pfx_nft_do_chain_inet+0x10/0x10 [nf_tables] > ? __pfx_ipt_do_table+0x10/0x10 [ip_tables] > nf_hook_slow+0xbe/0x210 > ? lock_is_held_type+0xb0/0x180 > ip_local_deliver+0x2d0/0x4a0 > ? __pfx_ip_local_deliver+0x10/0x10 > ? __pfx_ip_local_deliver_finish+0x10/0x10 > ? ip_rcv_finish_core+0x75b/0x1470 > ? lock_is_held_type+0xb0/0x180 > ip_list_rcv_finish+0x7f8/0xbb0 > ? ip_sublist_rcv+0x106/0x2f0 > ? __pfx_ip_list_rcv_finish+0x10/0x10 > ? __lock_release.isra.0+0x69/0x1a0 > ip_sublist_rcv+0x8b/0x2f0 > ? __pfx_ip_sublist_rcv+0x10/0x10 > ? __pfx_ip_rcv_finish+0x10/0x10 > ? ip_rcv_core+0x619/0xd00 > ? kasan_save_stack+0x2f/0x50 > ip_list_rcv+0x2dd/0x440 > ? asm_common_interrupt+0x26/0x40 > ? __pfx_ip_list_rcv+0x10/0x10 > ? drm_atomic_helper_commit_planes+0x3bd/0x1040 [drm_kms_helper] > ? commit_tail+0x204/0x4b0 [drm_kms_helper] > ? __lock_acquire+0x691/0xd00 > __netif_receive_skb_list_core+0x6bf/0xa10 > ? __pfx___netif_receive_skb_list_core+0x10/0x10 > ? lock_acquire.part.0+0xc8/0x240 > ? netif_receive_skb_list_internal+0x382/0xc90 > ? lock_acquire+0x11a/0x140 > netif_receive_skb_list_internal+0x603/0xc90 > ? dev_gro_receive+0x1e0/0x15f0 > ? __pfx_netif_receive_skb_list_internal+0x10/0x10 > ? napi_build_skb+0x55/0x1e0 > ? i40e_process_skb_fields+0x4a6/0xea0 [i40e] > ? i40e_clean_rx_irq+0x96f/0x2140 [i40e] > napi_complete_done+0x1a4/0x900 > ? __pfx_napi_complete_done+0x10/0x10 > i40e_napi_poll+0x408/0xb70 [i40e] > ? __pfx_i40e_napi_poll+0x10/0x10 [i40e] > __napi_poll+0x351/0x520 > net_rx_action+0x446/0xc30 > ? __pfx_net_rx_action+0x10/0x10 > ? do_raw_spin_unlock+0x59/0x230 > ? lock_release.part.0+0x1c/0x50 > ? sched_clock_cpu+0x69/0x630 > ? mark_held_locks+0x40/0x70 > handle_softirqs+0x1de/0x830 > ? __pfx_handle_softirqs+0x10/0x10 > ? irqtime_account_irq+0x3e/0x2d0 > __irq_exit_rcu+0x164/0x290 > irq_exit_rcu+0xe/0x20 > common_interrupt+0x85/0xa0 > </IRQ> > <TASK> > asm_common_interrupt+0x26/0x40 > RIP: 0010:memcpy_toio+0xa3/0x120 > Code: 5c e9 d1 59 9f 01 48 85 db 74 ee 40 f6 c5 01 75 49 48 83 fb 01 76 06 40 f6 c5 02 75 29 48 89 d9 48 89 ef 4c 89 e6 48 c1 e9 02 <f3> a5 f6 c3 02 74 02 66 a5 f6 c3 01 74 01 a4 48 83 c4 18 5b 5d 41 > RSP: 0018:ffff88811b3a7538 EFLAGS: 00010206 > RAX: 0000000000000000 RBX: 0000000000001000 RCX: 00000000000003f0 Try to revert 4333ab90aaae ("rhashtable: use private lockdep class for all locks.") Thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] rhashtable: Use separate lockdep keys for each lock 2026-09-15 4:06 ` Eric Dumazet @ 2026-09-15 6:04 ` Herbert Xu 2026-09-15 21:06 ` NeilBrown 2026-09-16 8:00 ` [v2 PATCH] " Herbert Xu 0 siblings, 2 replies; 7+ messages in thread From: Herbert Xu @ 2026-09-15 6:04 UTC (permalink / raw) To: Eric Dumazet Cc: Shin'ichiro Kawasaki, syzbot, bridge, davem, horms, idosch, kuba, linux-kernel, netdev, pabeni, razor, steffen.klassert, syzkaller-bugs, Thomas Graf, linux-crypto, NeilBrown, quanyeyang On Mon, Sep 14, 2026 at 09:06:49PM -0700, Eric Dumazet wrote: > > Try to revert 4333ab90aaae ("rhashtable: use private lockdep class for > all locks.") Yes this is indeed buggy. I know nothing about lockdep but Gemini reckons that it should use separate keys instead of different depths which seems fair enough: ---8<--- Use separate lockdep keys for the different types of locks in rhashtable (mutex, spin lock, and bucket locks). They are separate and not normally nested with respect to each other. Also move the rhashtable_init/rhltable_init kdoc to the header file as that's where the macros are defined. Fixes: 4333ab90aaae ("rhashtable: use private lockdep class for all locks.") Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com Assisted-by: Gemini:gemini-3.6-flash Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h index 0e1b172a4f6c..afbc12ba71f5 100644 --- a/include/linux/rhashtable-types.h +++ b/include/linux/rhashtable-types.h @@ -70,6 +70,14 @@ struct rhashtable_params { rht_obj_cmpfn_t obj_cmpfn; }; +struct rhashtable_lockdep_keys { +#ifdef CONFIG_LOCKDEP + struct lock_class_key lock_key; + struct lock_class_key mutex_key; + struct lock_class_key bucket_key; +#endif +}; + /** * struct rhashtable - Hash table handle * @tbl: Bucket table @@ -141,24 +149,77 @@ struct rhashtable_iter { int __rhashtable_init_noprof(struct rhashtable *ht, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhashtable_init_noprof(ht, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhashtable_init_noprof(ht, params, &__key); \ + __rhashtable_init_noprof(ht, params, &__keys); \ }) + +/** + * rhashtable_init - initialize a new hash table + * @ht: hash table to be initialized + * @params: configuration parameters + * + * Initializes a new hash table based on the provided configuration + * parameters. A table can be configured either with a variable or + * fixed length key: + * + * Configuration Example 1: Fixed length keys + * struct test_obj { + * int key; + * void * my_member; + * struct rhash_head node; + * }; + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .key_offset = offsetof(struct test_obj, key), + * .key_len = sizeof(int), + * .hashfn = jhash, + * }; + * + * Configuration Example 2: Variable length keys + * struct test_obj { + * [...] + * struct rhash_head node; + * }; + * + * u32 my_hash_fn(const void *data, u32 len, u32 seed) + * { + * struct test_obj *obj = data; + * + * return [... hash ...]; + * } + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .hashfn = jhash, + * .obj_hashfn = my_hash_fn, + * }; + */ #define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__)) int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhltable_init_noprof(hlt, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhltable_init_noprof(hlt, params, &__key); \ + __rhltable_init_noprof(hlt, params, &__keys); \ }) + +/** + * rhltable_init - initialize a new hash list table + * @hlt: hash list table to be initialized + * @params: configuration parameters + * + * Initializes a new hash list table. + * + * See documentation for rhashtable_init. + */ #define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__)) #endif /* _LINUX_RHASHTABLE_TYPES_H */ diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 6c5e6d9accba..ec853c1b9af3 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -328,8 +328,7 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl, local_irq_save(flags); bit_spin_lock(0, (unsigned long *)bucket); - /* subclass 0 is used for ->lock and 1 for ->mutex. 2+ for bitlocks */ - lock_acquire_exclusive(&tbl->dep_map, subclass+2, 0, NULL, _THIS_IP_); + lock_acquire_exclusive(&tbl->dep_map, subclass, 0, NULL, _THIS_IP_); return flags; } diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 5da0e53a8d42..918f15a2ac69 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -432,7 +432,7 @@ static void rht_deferred_worker(struct work_struct *work) int err = 0; ht = container_of(work, struct rhashtable, run_work); - mutex_lock_nested(&ht->mutex, 1); + mutex_lock(&ht->mutex); tbl = rht_dereference(ht->tbl, ht); tbl = rhashtable_last_table(ht, tbl); @@ -1122,51 +1122,9 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) return jhash2(key, length, seed); } -/** - * rhashtable_init - initialize a new hash table - * @ht: hash table to be initialized - * @params: configuration parameters - * - * Initializes a new hash table based on the provided configuration - * parameters. A table can be configured either with a variable or - * fixed length key: - * - * Configuration Example 1: Fixed length keys - * struct test_obj { - * int key; - * void * my_member; - * struct rhash_head node; - * }; - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .key_offset = offsetof(struct test_obj, key), - * .key_len = sizeof(int), - * .hashfn = jhash, - * }; - * - * Configuration Example 2: Variable length keys - * struct test_obj { - * [...] - * struct rhash_head node; - * }; - * - * u32 my_hash_fn(const void *data, u32 len, u32 seed) - * { - * struct test_obj *obj = data; - * - * return [... hash ...]; - * } - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .hashfn = jhash, - * .obj_hashfn = my_hash_fn, - * }; - */ int __rhashtable_init_noprof(struct rhashtable *ht, - const struct rhashtable_params *params, - struct lock_class_key *key) + const struct rhashtable_params *params, + struct rhashtable_lockdep_keys *keys) { struct bucket_table *tbl; size_t size; @@ -1176,13 +1134,11 @@ int __rhashtable_init_noprof(struct rhashtable *ht, return -EINVAL; memset(ht, 0, sizeof(*ht)); - /* mutex_lock must use nesting level 1 */ - mutex_init_with_key(&ht->mutex, key); + mutex_init_with_key(&ht->mutex, &keys->mutex_key); spin_lock_init(&ht->lock); - /* spin_lock can use nesting level 0 */ - lockdep_set_class(&ht->lock, key); + lockdep_set_class(&ht->lock, &keys->lock_key); #ifdef CONFIG_LOCKDEP - ht->lockdep_key = key; + ht->lockdep_key = &keys->bucket_key; #endif memcpy(&ht->p, params, sizeof(*params)); @@ -1236,22 +1192,13 @@ int __rhashtable_init_noprof(struct rhashtable *ht, } EXPORT_SYMBOL_GPL(__rhashtable_init_noprof); -/** - * rhltable_init - initialize a new hash list table - * @hlt: hash list table to be initialized - * @params: configuration parameters - * - * Initializes a new hash list table. - * - * See documentation for rhashtable_init. - */ int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key) + struct rhashtable_lockdep_keys *keys) { int err; - err = __rhashtable_init_noprof(&hlt->ht, params, key); + err = __rhashtable_init_noprof(&hlt->ht, params, keys); hlt->ht.rhlist = true; return err; } diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 85a615e74591..b767a38a74f9 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -477,7 +477,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt) ht = &rhlt->ht; /* Take the mutex to avoid RCU warning */ - mutex_lock_nested(&ht->mutex, 1); + mutex_lock(&ht->mutex); tbl = rht_dereference(ht->tbl, ht); for (i = 0; i < tbl->size; i++) { struct rhash_head *pos, *next; -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] rhashtable: Use separate lockdep keys for each lock 2026-09-15 6:04 ` [PATCH] rhashtable: Use separate lockdep keys for each lock Herbert Xu @ 2026-09-15 21:06 ` NeilBrown 2026-09-16 8:00 ` [v2 PATCH] " Herbert Xu 1 sibling, 0 replies; 7+ messages in thread From: NeilBrown @ 2026-09-15 21:06 UTC (permalink / raw) To: Herbert Xu Cc: Eric Dumazet, Shin'ichiro Kawasaki, syzbot, bridge, davem, horms, idosch, kuba, linux-kernel, netdev, pabeni, razor, steffen.klassert, syzkaller-bugs, Thomas Graf, linux-crypto, quanyeyang On Tue, 15 Sep 2026, Herbert Xu wrote: > On Mon, Sep 14, 2026 at 09:06:49PM -0700, Eric Dumazet wrote: > > > > Try to revert 4333ab90aaae ("rhashtable: use private lockdep class for > > all locks.") > > Yes this is indeed buggy. I know nothing about lockdep but Gemini > reckons that it should use separate keys instead of different > depths which seems fair enough: > > ---8<--- > Use separate lockdep keys for the different types of locks in > rhashtable (mutex, spin lock, and bucket locks). They are > separate and not normally nested with respect to each other. > > Also move the rhashtable_init/rhltable_init kdoc to the header > file as that's where the macros are defined. > > Fixes: 4333ab90aaae ("rhashtable: use private lockdep class for all locks.") > Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com > Assisted-by: Gemini:gemini-3.6-flash > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> That's a much better approach - thanks for that. Reviewed-by: NeilBrown <neil@brown.name> Thanks, NeilBrown > > diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h > index 0e1b172a4f6c..afbc12ba71f5 100644 > --- a/include/linux/rhashtable-types.h > +++ b/include/linux/rhashtable-types.h > @@ -70,6 +70,14 @@ struct rhashtable_params { > rht_obj_cmpfn_t obj_cmpfn; > }; > > +struct rhashtable_lockdep_keys { > +#ifdef CONFIG_LOCKDEP > + struct lock_class_key lock_key; > + struct lock_class_key mutex_key; > + struct lock_class_key bucket_key; > +#endif > +}; > + > /** > * struct rhashtable - Hash table handle > * @tbl: Bucket table > @@ -141,24 +149,77 @@ struct rhashtable_iter { > > int __rhashtable_init_noprof(struct rhashtable *ht, > const struct rhashtable_params *params, > - struct lock_class_key *key); > + struct rhashtable_lockdep_keys *keys); > #define rhashtable_init_noprof(ht, params) \ > ({ \ > - static struct lock_class_key __key; \ > + static struct rhashtable_lockdep_keys __keys; \ > \ > - __rhashtable_init_noprof(ht, params, &__key); \ > + __rhashtable_init_noprof(ht, params, &__keys); \ > }) > + > +/** > + * rhashtable_init - initialize a new hash table > + * @ht: hash table to be initialized > + * @params: configuration parameters > + * > + * Initializes a new hash table based on the provided configuration > + * parameters. A table can be configured either with a variable or > + * fixed length key: > + * > + * Configuration Example 1: Fixed length keys > + * struct test_obj { > + * int key; > + * void * my_member; > + * struct rhash_head node; > + * }; > + * > + * struct rhashtable_params params = { > + * .head_offset = offsetof(struct test_obj, node), > + * .key_offset = offsetof(struct test_obj, key), > + * .key_len = sizeof(int), > + * .hashfn = jhash, > + * }; > + * > + * Configuration Example 2: Variable length keys > + * struct test_obj { > + * [...] > + * struct rhash_head node; > + * }; > + * > + * u32 my_hash_fn(const void *data, u32 len, u32 seed) > + * { > + * struct test_obj *obj = data; > + * > + * return [... hash ...]; > + * } > + * > + * struct rhashtable_params params = { > + * .head_offset = offsetof(struct test_obj, node), > + * .hashfn = jhash, > + * .obj_hashfn = my_hash_fn, > + * }; > + */ > #define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__)) > > int __rhltable_init_noprof(struct rhltable *hlt, > const struct rhashtable_params *params, > - struct lock_class_key *key); > + struct rhashtable_lockdep_keys *keys); > #define rhltable_init_noprof(hlt, params) \ > ({ \ > - static struct lock_class_key __key; \ > + static struct rhashtable_lockdep_keys __keys; \ > \ > - __rhltable_init_noprof(hlt, params, &__key); \ > + __rhltable_init_noprof(hlt, params, &__keys); \ > }) > + > +/** > + * rhltable_init - initialize a new hash list table > + * @hlt: hash list table to be initialized > + * @params: configuration parameters > + * > + * Initializes a new hash list table. > + * > + * See documentation for rhashtable_init. > + */ > #define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__)) > > #endif /* _LINUX_RHASHTABLE_TYPES_H */ > diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h > index 6c5e6d9accba..ec853c1b9af3 100644 > --- a/include/linux/rhashtable.h > +++ b/include/linux/rhashtable.h > @@ -328,8 +328,7 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl, > > local_irq_save(flags); > bit_spin_lock(0, (unsigned long *)bucket); > - /* subclass 0 is used for ->lock and 1 for ->mutex. 2+ for bitlocks */ > - lock_acquire_exclusive(&tbl->dep_map, subclass+2, 0, NULL, _THIS_IP_); > + lock_acquire_exclusive(&tbl->dep_map, subclass, 0, NULL, _THIS_IP_); > return flags; > } > > diff --git a/lib/rhashtable.c b/lib/rhashtable.c > index 5da0e53a8d42..918f15a2ac69 100644 > --- a/lib/rhashtable.c > +++ b/lib/rhashtable.c > @@ -432,7 +432,7 @@ static void rht_deferred_worker(struct work_struct *work) > int err = 0; > > ht = container_of(work, struct rhashtable, run_work); > - mutex_lock_nested(&ht->mutex, 1); > + mutex_lock(&ht->mutex); > > tbl = rht_dereference(ht->tbl, ht); > tbl = rhashtable_last_table(ht, tbl); > @@ -1122,51 +1122,9 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) > return jhash2(key, length, seed); > } > > -/** > - * rhashtable_init - initialize a new hash table > - * @ht: hash table to be initialized > - * @params: configuration parameters > - * > - * Initializes a new hash table based on the provided configuration > - * parameters. A table can be configured either with a variable or > - * fixed length key: > - * > - * Configuration Example 1: Fixed length keys > - * struct test_obj { > - * int key; > - * void * my_member; > - * struct rhash_head node; > - * }; > - * > - * struct rhashtable_params params = { > - * .head_offset = offsetof(struct test_obj, node), > - * .key_offset = offsetof(struct test_obj, key), > - * .key_len = sizeof(int), > - * .hashfn = jhash, > - * }; > - * > - * Configuration Example 2: Variable length keys > - * struct test_obj { > - * [...] > - * struct rhash_head node; > - * }; > - * > - * u32 my_hash_fn(const void *data, u32 len, u32 seed) > - * { > - * struct test_obj *obj = data; > - * > - * return [... hash ...]; > - * } > - * > - * struct rhashtable_params params = { > - * .head_offset = offsetof(struct test_obj, node), > - * .hashfn = jhash, > - * .obj_hashfn = my_hash_fn, > - * }; > - */ > int __rhashtable_init_noprof(struct rhashtable *ht, > - const struct rhashtable_params *params, > - struct lock_class_key *key) > + const struct rhashtable_params *params, > + struct rhashtable_lockdep_keys *keys) > { > struct bucket_table *tbl; > size_t size; > @@ -1176,13 +1134,11 @@ int __rhashtable_init_noprof(struct rhashtable *ht, > return -EINVAL; > > memset(ht, 0, sizeof(*ht)); > - /* mutex_lock must use nesting level 1 */ > - mutex_init_with_key(&ht->mutex, key); > + mutex_init_with_key(&ht->mutex, &keys->mutex_key); > spin_lock_init(&ht->lock); > - /* spin_lock can use nesting level 0 */ > - lockdep_set_class(&ht->lock, key); > + lockdep_set_class(&ht->lock, &keys->lock_key); > #ifdef CONFIG_LOCKDEP > - ht->lockdep_key = key; > + ht->lockdep_key = &keys->bucket_key; > #endif > memcpy(&ht->p, params, sizeof(*params)); > > @@ -1236,22 +1192,13 @@ int __rhashtable_init_noprof(struct rhashtable *ht, > } > EXPORT_SYMBOL_GPL(__rhashtable_init_noprof); > > -/** > - * rhltable_init - initialize a new hash list table > - * @hlt: hash list table to be initialized > - * @params: configuration parameters > - * > - * Initializes a new hash list table. > - * > - * See documentation for rhashtable_init. > - */ > int __rhltable_init_noprof(struct rhltable *hlt, > const struct rhashtable_params *params, > - struct lock_class_key *key) > + struct rhashtable_lockdep_keys *keys) > { > int err; > > - err = __rhashtable_init_noprof(&hlt->ht, params, key); > + err = __rhashtable_init_noprof(&hlt->ht, params, keys); > hlt->ht.rhlist = true; > return err; > } > diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c > index 85a615e74591..b767a38a74f9 100644 > --- a/lib/test_rhashtable.c > +++ b/lib/test_rhashtable.c > @@ -477,7 +477,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt) > > ht = &rhlt->ht; > /* Take the mutex to avoid RCU warning */ > - mutex_lock_nested(&ht->mutex, 1); > + mutex_lock(&ht->mutex); > tbl = rht_dereference(ht->tbl, ht); > for (i = 0; i < tbl->size; i++) { > struct rhash_head *pos, *next; > -- > Email: Herbert Xu <herbert@gondor.apana.org.au> > Home Page: http://gondor.apana.org.au/~herbert/ > PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [v2 PATCH] rhashtable: Use separate lockdep keys for each lock 2026-09-15 6:04 ` [PATCH] rhashtable: Use separate lockdep keys for each lock Herbert Xu 2026-09-15 21:06 ` NeilBrown @ 2026-09-16 8:00 ` Herbert Xu 2026-09-16 8:46 ` [v3 " Herbert Xu 1 sibling, 1 reply; 7+ messages in thread From: Herbert Xu @ 2026-09-16 8:00 UTC (permalink / raw) To: Eric Dumazet Cc: Shin'ichiro Kawasaki, syzbot, davem, horms, idosch, kuba, linux-kernel, pabeni, razor, steffen.klassert, syzkaller-bugs, Thomas Graf, linux-crypto, NeilBrown, quanyeyang v2 fixes the build failure when LOCKDEP is disabled. ---8<--- Use separate lockdep keys for the different types of locks in rhashtable (mutex, spin lock, and bucket locks). They are separate and not normally nested with respect to each other. Also move the rhashtable_init/rhltable_init kdoc to the header file as that's where the macros are defined. Fixes: 4333ab90aaae ("rhashtable: use private lockdep class for all locks.") Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com Assisted-by: Gemini:gemini-3.6-flash Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Reviewed-by: NeilBrown <neil@brown.name> diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h index 0e1b172a4f6c..3576b8f08aff 100644 --- a/include/linux/rhashtable-types.h +++ b/include/linux/rhashtable-types.h @@ -70,6 +70,12 @@ struct rhashtable_params { rht_obj_cmpfn_t obj_cmpfn; }; +struct rhashtable_lockdep_keys { + struct lock_class_key lock_key; + struct lock_class_key mutex_key; + struct lock_class_key bucket_key; +}; + /** * struct rhashtable - Hash table handle * @tbl: Bucket table @@ -141,24 +147,77 @@ struct rhashtable_iter { int __rhashtable_init_noprof(struct rhashtable *ht, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhashtable_init_noprof(ht, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhashtable_init_noprof(ht, params, &__key); \ + __rhashtable_init_noprof(ht, params, &__keys); \ }) + +/** + * rhashtable_init - initialize a new hash table + * @ht: hash table to be initialized + * @params: configuration parameters + * + * Initializes a new hash table based on the provided configuration + * parameters. A table can be configured either with a variable or + * fixed length key: + * + * Configuration Example 1: Fixed length keys + * struct test_obj { + * int key; + * void * my_member; + * struct rhash_head node; + * }; + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .key_offset = offsetof(struct test_obj, key), + * .key_len = sizeof(int), + * .hashfn = jhash, + * }; + * + * Configuration Example 2: Variable length keys + * struct test_obj { + * [...] + * struct rhash_head node; + * }; + * + * u32 my_hash_fn(const void *data, u32 len, u32 seed) + * { + * struct test_obj *obj = data; + * + * return [... hash ...]; + * } + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .hashfn = jhash, + * .obj_hashfn = my_hash_fn, + * }; + */ #define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__)) int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhltable_init_noprof(hlt, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhltable_init_noprof(hlt, params, &__key); \ + __rhltable_init_noprof(hlt, params, &__keys); \ }) + +/** + * rhltable_init - initialize a new hash list table + * @hlt: hash list table to be initialized + * @params: configuration parameters + * + * Initializes a new hash list table. + * + * See documentation for rhashtable_init. + */ #define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__)) #endif /* _LINUX_RHASHTABLE_TYPES_H */ diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 6c5e6d9accba..ec853c1b9af3 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -328,8 +328,7 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl, local_irq_save(flags); bit_spin_lock(0, (unsigned long *)bucket); - /* subclass 0 is used for ->lock and 1 for ->mutex. 2+ for bitlocks */ - lock_acquire_exclusive(&tbl->dep_map, subclass+2, 0, NULL, _THIS_IP_); + lock_acquire_exclusive(&tbl->dep_map, subclass, 0, NULL, _THIS_IP_); return flags; } diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 5da0e53a8d42..918f15a2ac69 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -432,7 +432,7 @@ static void rht_deferred_worker(struct work_struct *work) int err = 0; ht = container_of(work, struct rhashtable, run_work); - mutex_lock_nested(&ht->mutex, 1); + mutex_lock(&ht->mutex); tbl = rht_dereference(ht->tbl, ht); tbl = rhashtable_last_table(ht, tbl); @@ -1122,51 +1122,9 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) return jhash2(key, length, seed); } -/** - * rhashtable_init - initialize a new hash table - * @ht: hash table to be initialized - * @params: configuration parameters - * - * Initializes a new hash table based on the provided configuration - * parameters. A table can be configured either with a variable or - * fixed length key: - * - * Configuration Example 1: Fixed length keys - * struct test_obj { - * int key; - * void * my_member; - * struct rhash_head node; - * }; - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .key_offset = offsetof(struct test_obj, key), - * .key_len = sizeof(int), - * .hashfn = jhash, - * }; - * - * Configuration Example 2: Variable length keys - * struct test_obj { - * [...] - * struct rhash_head node; - * }; - * - * u32 my_hash_fn(const void *data, u32 len, u32 seed) - * { - * struct test_obj *obj = data; - * - * return [... hash ...]; - * } - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .hashfn = jhash, - * .obj_hashfn = my_hash_fn, - * }; - */ int __rhashtable_init_noprof(struct rhashtable *ht, - const struct rhashtable_params *params, - struct lock_class_key *key) + const struct rhashtable_params *params, + struct rhashtable_lockdep_keys *keys) { struct bucket_table *tbl; size_t size; @@ -1176,13 +1134,11 @@ int __rhashtable_init_noprof(struct rhashtable *ht, return -EINVAL; memset(ht, 0, sizeof(*ht)); - /* mutex_lock must use nesting level 1 */ - mutex_init_with_key(&ht->mutex, key); + mutex_init_with_key(&ht->mutex, &keys->mutex_key); spin_lock_init(&ht->lock); - /* spin_lock can use nesting level 0 */ - lockdep_set_class(&ht->lock, key); + lockdep_set_class(&ht->lock, &keys->lock_key); #ifdef CONFIG_LOCKDEP - ht->lockdep_key = key; + ht->lockdep_key = &keys->bucket_key; #endif memcpy(&ht->p, params, sizeof(*params)); @@ -1236,22 +1192,13 @@ int __rhashtable_init_noprof(struct rhashtable *ht, } EXPORT_SYMBOL_GPL(__rhashtable_init_noprof); -/** - * rhltable_init - initialize a new hash list table - * @hlt: hash list table to be initialized - * @params: configuration parameters - * - * Initializes a new hash list table. - * - * See documentation for rhashtable_init. - */ int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key) + struct rhashtable_lockdep_keys *keys) { int err; - err = __rhashtable_init_noprof(&hlt->ht, params, key); + err = __rhashtable_init_noprof(&hlt->ht, params, keys); hlt->ht.rhlist = true; return err; } diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 85a615e74591..b767a38a74f9 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -477,7 +477,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt) ht = &rhlt->ht; /* Take the mutex to avoid RCU warning */ - mutex_lock_nested(&ht->mutex, 1); + mutex_lock(&ht->mutex); tbl = rht_dereference(ht->tbl, ht); for (i = 0; i < tbl->size; i++) { struct rhash_head *pos, *next; -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 7+ messages in thread
* [v3 PATCH] rhashtable: Use separate lockdep keys for each lock 2026-09-16 8:00 ` [v2 PATCH] " Herbert Xu @ 2026-09-16 8:46 ` Herbert Xu 0 siblings, 0 replies; 7+ messages in thread From: Herbert Xu @ 2026-09-16 8:46 UTC (permalink / raw) To: Eric Dumazet Cc: Shin'ichiro Kawasaki, syzbot, davem, horms, idosch, kuba, linux-kernel, pabeni, razor, steffen.klassert, syzkaller-bugs, Thomas Graf, linux-crypto, NeilBrown, quanyeyang v3 removes an obsolete comment regarding the use of nesting level 2 or more. ---8<--- Use separate lockdep keys for the different types of locks in rhashtable (mutex, spin lock, and bucket locks). They are separate and not normally nested with respect to each other. Also move the rhashtable_init/rhltable_init kdoc to the header file as that's where the macros are defined. Fixes: 4333ab90aaae ("rhashtable: use private lockdep class for all locks.") Reported-by: syzbot+4d0e4d2db6dfde01b52f@syzkaller.appspotmail.com Assisted-by: Gemini:gemini-3.6-flash Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Reviewed-by: NeilBrown <neil@brown.name> diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h index 0e1b172a4f6c..3576b8f08aff 100644 --- a/include/linux/rhashtable-types.h +++ b/include/linux/rhashtable-types.h @@ -70,6 +70,12 @@ struct rhashtable_params { rht_obj_cmpfn_t obj_cmpfn; }; +struct rhashtable_lockdep_keys { + struct lock_class_key lock_key; + struct lock_class_key mutex_key; + struct lock_class_key bucket_key; +}; + /** * struct rhashtable - Hash table handle * @tbl: Bucket table @@ -141,24 +147,77 @@ struct rhashtable_iter { int __rhashtable_init_noprof(struct rhashtable *ht, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhashtable_init_noprof(ht, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhashtable_init_noprof(ht, params, &__key); \ + __rhashtable_init_noprof(ht, params, &__keys); \ }) + +/** + * rhashtable_init - initialize a new hash table + * @ht: hash table to be initialized + * @params: configuration parameters + * + * Initializes a new hash table based on the provided configuration + * parameters. A table can be configured either with a variable or + * fixed length key: + * + * Configuration Example 1: Fixed length keys + * struct test_obj { + * int key; + * void * my_member; + * struct rhash_head node; + * }; + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .key_offset = offsetof(struct test_obj, key), + * .key_len = sizeof(int), + * .hashfn = jhash, + * }; + * + * Configuration Example 2: Variable length keys + * struct test_obj { + * [...] + * struct rhash_head node; + * }; + * + * u32 my_hash_fn(const void *data, u32 len, u32 seed) + * { + * struct test_obj *obj = data; + * + * return [... hash ...]; + * } + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .hashfn = jhash, + * .obj_hashfn = my_hash_fn, + * }; + */ #define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__)) int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhltable_init_noprof(hlt, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhltable_init_noprof(hlt, params, &__key); \ + __rhltable_init_noprof(hlt, params, &__keys); \ }) + +/** + * rhltable_init - initialize a new hash list table + * @hlt: hash list table to be initialized + * @params: configuration parameters + * + * Initializes a new hash list table. + * + * See documentation for rhashtable_init. + */ #define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__)) #endif /* _LINUX_RHASHTABLE_TYPES_H */ diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 6c5e6d9accba..ec853c1b9af3 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -328,8 +328,7 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl, local_irq_save(flags); bit_spin_lock(0, (unsigned long *)bucket); - /* subclass 0 is used for ->lock and 1 for ->mutex. 2+ for bitlocks */ - lock_acquire_exclusive(&tbl->dep_map, subclass+2, 0, NULL, _THIS_IP_); + lock_acquire_exclusive(&tbl->dep_map, subclass, 0, NULL, _THIS_IP_); return flags; } diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 5da0e53a8d42..a3a4a1f7751e 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -207,7 +207,6 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht, return NULL; #ifdef CONFIG_LOCKDEP - /* bitlocks must use nesting level 2 or more */ lockdep_init_map(&tbl->dep_map, "rhashtable_bucket", ht->lockdep_key, 0); #endif @@ -432,7 +431,7 @@ static void rht_deferred_worker(struct work_struct *work) int err = 0; ht = container_of(work, struct rhashtable, run_work); - mutex_lock_nested(&ht->mutex, 1); + mutex_lock(&ht->mutex); tbl = rht_dereference(ht->tbl, ht); tbl = rhashtable_last_table(ht, tbl); @@ -1122,51 +1121,9 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) return jhash2(key, length, seed); } -/** - * rhashtable_init - initialize a new hash table - * @ht: hash table to be initialized - * @params: configuration parameters - * - * Initializes a new hash table based on the provided configuration - * parameters. A table can be configured either with a variable or - * fixed length key: - * - * Configuration Example 1: Fixed length keys - * struct test_obj { - * int key; - * void * my_member; - * struct rhash_head node; - * }; - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .key_offset = offsetof(struct test_obj, key), - * .key_len = sizeof(int), - * .hashfn = jhash, - * }; - * - * Configuration Example 2: Variable length keys - * struct test_obj { - * [...] - * struct rhash_head node; - * }; - * - * u32 my_hash_fn(const void *data, u32 len, u32 seed) - * { - * struct test_obj *obj = data; - * - * return [... hash ...]; - * } - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .hashfn = jhash, - * .obj_hashfn = my_hash_fn, - * }; - */ int __rhashtable_init_noprof(struct rhashtable *ht, - const struct rhashtable_params *params, - struct lock_class_key *key) + const struct rhashtable_params *params, + struct rhashtable_lockdep_keys *keys) { struct bucket_table *tbl; size_t size; @@ -1176,13 +1133,11 @@ int __rhashtable_init_noprof(struct rhashtable *ht, return -EINVAL; memset(ht, 0, sizeof(*ht)); - /* mutex_lock must use nesting level 1 */ - mutex_init_with_key(&ht->mutex, key); + mutex_init_with_key(&ht->mutex, &keys->mutex_key); spin_lock_init(&ht->lock); - /* spin_lock can use nesting level 0 */ - lockdep_set_class(&ht->lock, key); + lockdep_set_class(&ht->lock, &keys->lock_key); #ifdef CONFIG_LOCKDEP - ht->lockdep_key = key; + ht->lockdep_key = &keys->bucket_key; #endif memcpy(&ht->p, params, sizeof(*params)); @@ -1236,22 +1191,13 @@ int __rhashtable_init_noprof(struct rhashtable *ht, } EXPORT_SYMBOL_GPL(__rhashtable_init_noprof); -/** - * rhltable_init - initialize a new hash list table - * @hlt: hash list table to be initialized - * @params: configuration parameters - * - * Initializes a new hash list table. - * - * See documentation for rhashtable_init. - */ int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key) + struct rhashtable_lockdep_keys *keys) { int err; - err = __rhashtable_init_noprof(&hlt->ht, params, key); + err = __rhashtable_init_noprof(&hlt->ht, params, keys); hlt->ht.rhlist = true; return err; } diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 85a615e74591..b767a38a74f9 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -477,7 +477,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt) ht = &rhlt->ht; /* Take the mutex to avoid RCU warning */ - mutex_lock_nested(&ht->mutex, 1); + mutex_lock(&ht->mutex); tbl = rht_dereference(ht->tbl, ht); for (i = 0; i < tbl->size; i++) { struct rhash_head *pos, *next; -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-16 8:47 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-09-13 1:31 [syzbot] [bridge?] WARNING: locking bug in match_held_lock syzbot 2026-09-15 3:40 ` Shin'ichiro Kawasaki 2026-09-15 4:06 ` Eric Dumazet 2026-09-15 6:04 ` [PATCH] rhashtable: Use separate lockdep keys for each lock Herbert Xu 2026-09-15 21:06 ` NeilBrown 2026-09-16 8:00 ` [v2 PATCH] " Herbert Xu 2026-09-16 8:46 ` [v3 " Herbert Xu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®