diff mbox series

[v9,05/25] dept: Tie to Lockdep and IRQ tracing

Message ID 1675154394-25598-6-git-send-email-max.byungchul.park@gmail.com (mailing list archive)
State New
Headers show
Series DEPT(Dependency Tracker) | expand

Commit Message

Byungchul Park Jan. 31, 2023, 8:39 a.m. UTC
Yes. How to place Dept in here looks so ugly. But it's inevitable as
long as relying on Lockdep. The way should be enhanced gradually.

   1. Basically relies on Lockdep to track typical locks and IRQ things.

   2. Dept fails to recognize IRQ situation so it generates false alarms
      when raw_local_irq_*() APIs are used. So made it track those too.

   3. Lockdep doesn't track the outmost {hard,soft}irq entracnes but
      Dept makes use of it. So made it track those too.

Signed-off-by: Byungchul Park <max.byungchul.park@gmail.com>
---
 include/linux/irqflags.h            |  22 ++++++--
 include/linux/local_lock_internal.h |   1 +
 include/linux/lockdep.h             | 102 ++++++++++++++++++++++++++++--------
 include/linux/lockdep_types.h       |   3 ++
 include/linux/mutex.h               |   1 +
 include/linux/percpu-rwsem.h        |   2 +-
 include/linux/rtmutex.h             |   1 +
 include/linux/rwlock_types.h        |   1 +
 include/linux/rwsem.h               |   1 +
 include/linux/seqlock.h             |   2 +-
 include/linux/spinlock_types_raw.h  |   3 ++
 include/linux/srcu.h                |   2 +-
 kernel/dependency/dept.c            |   4 +-
 kernel/locking/lockdep.c            |  23 ++++++++
 14 files changed, 139 insertions(+), 29 deletions(-)

Comments

kernel test robot Feb. 1, 2023, 2:28 a.m. UTC | #1
Hi Byungchul,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tip/locking/core]
[also build test WARNING on tip/sched/core drm-misc/drm-misc-next linus/master v6.2-rc6 next-20230131]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Byungchul-Park/llist-Move-llist_-head-node-definition-to-types-h/20230131-164632
patch link:    https://lore.kernel.org/r/1675154394-25598-6-git-send-email-max.byungchul.park%40gmail.com
patch subject: [PATCH v9 05/25] dept: Tie to Lockdep and IRQ tracing
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20230201/202302011038.V1juoXv1-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ee619b0e7faff81e8b794e2adcdf9102d5bc83e8
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Byungchul-Park/llist-Move-llist_-head-node-definition-to-types-h/20230131-164632
        git checkout ee619b0e7faff81e8b794e2adcdf9102d5bc83e8
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash drivers/iommu/ drivers/scsi/qla2xxx/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/atomic.h:80,
                    from drivers/iommu/io-pgtable-arm.c:12:
   drivers/iommu/io-pgtable-arm.c: In function 'arm_lpae_install_table':
   include/linux/atomic/atomic-arch-fallback.h:60:32: error: implicit declaration of function 'arch_cmpxchg64'; did you mean 'arch_cmpxchg'? [-Werror=implicit-function-declaration]
      60 | #define arch_cmpxchg64_relaxed arch_cmpxchg64
         |                                ^~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1968:9: note: in expansion of macro 'arch_cmpxchg64_relaxed'
    1968 |         arch_cmpxchg64_relaxed(__ai_ptr, __VA_ARGS__); \
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/iommu/io-pgtable-arm.c:330:15: note: in expansion of macro 'cmpxchg64_relaxed'
     330 |         old = cmpxchg64_relaxed(ptep, curr, new);
         |               ^~~~~~~~~~~~~~~~~
   drivers/iommu/io-pgtable-arm.c: In function 'arm_lpae_do_selftests':
>> drivers/iommu/io-pgtable-arm.c:1296:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=]
    1296 | }
         | ^
   cc1: some warnings being treated as errors


vim +1296 drivers/iommu/io-pgtable-arm.c

fe4b991dcd84e0 Will Deacon        2014-11-17  1256  
fe4b991dcd84e0 Will Deacon        2014-11-17  1257  static int __init arm_lpae_do_selftests(void)
fe4b991dcd84e0 Will Deacon        2014-11-17  1258  {
9062c1d0bedacf Christophe JAILLET 2019-09-09  1259  	static const unsigned long pgsize[] __initconst = {
fe4b991dcd84e0 Will Deacon        2014-11-17  1260  		SZ_4K | SZ_2M | SZ_1G,
fe4b991dcd84e0 Will Deacon        2014-11-17  1261  		SZ_16K | SZ_32M,
fe4b991dcd84e0 Will Deacon        2014-11-17  1262  		SZ_64K | SZ_512M,
fe4b991dcd84e0 Will Deacon        2014-11-17  1263  	};
fe4b991dcd84e0 Will Deacon        2014-11-17  1264  
9062c1d0bedacf Christophe JAILLET 2019-09-09  1265  	static const unsigned int ias[] __initconst = {
fe4b991dcd84e0 Will Deacon        2014-11-17  1266  		32, 36, 40, 42, 44, 48,
fe4b991dcd84e0 Will Deacon        2014-11-17  1267  	};
fe4b991dcd84e0 Will Deacon        2014-11-17  1268  
fe4b991dcd84e0 Will Deacon        2014-11-17  1269  	int i, j, pass = 0, fail = 0;
ca25ec247aadbf Robin Murphy       2022-08-15  1270  	struct device dev;
fe4b991dcd84e0 Will Deacon        2014-11-17  1271  	struct io_pgtable_cfg cfg = {
fe4b991dcd84e0 Will Deacon        2014-11-17  1272  		.tlb = &dummy_tlb_ops,
fe4b991dcd84e0 Will Deacon        2014-11-17  1273  		.oas = 48,
4f41845b340783 Will Deacon        2019-06-25  1274  		.coherent_walk = true,
ca25ec247aadbf Robin Murphy       2022-08-15  1275  		.iommu_dev = &dev,
fe4b991dcd84e0 Will Deacon        2014-11-17  1276  	};
fe4b991dcd84e0 Will Deacon        2014-11-17  1277  
ca25ec247aadbf Robin Murphy       2022-08-15  1278  	/* __arm_lpae_alloc_pages() merely needs dev_to_node() to work */
ca25ec247aadbf Robin Murphy       2022-08-15  1279  	set_dev_node(&dev, NUMA_NO_NODE);
ca25ec247aadbf Robin Murphy       2022-08-15  1280  
fe4b991dcd84e0 Will Deacon        2014-11-17  1281  	for (i = 0; i < ARRAY_SIZE(pgsize); ++i) {
fe4b991dcd84e0 Will Deacon        2014-11-17  1282  		for (j = 0; j < ARRAY_SIZE(ias); ++j) {
fe4b991dcd84e0 Will Deacon        2014-11-17  1283  			cfg.pgsize_bitmap = pgsize[i];
fe4b991dcd84e0 Will Deacon        2014-11-17  1284  			cfg.ias = ias[j];
fe4b991dcd84e0 Will Deacon        2014-11-17  1285  			pr_info("selftest: pgsize_bitmap 0x%08lx, IAS %u\n",
fe4b991dcd84e0 Will Deacon        2014-11-17  1286  				pgsize[i], ias[j]);
fe4b991dcd84e0 Will Deacon        2014-11-17  1287  			if (arm_lpae_run_tests(&cfg))
fe4b991dcd84e0 Will Deacon        2014-11-17  1288  				fail++;
fe4b991dcd84e0 Will Deacon        2014-11-17  1289  			else
fe4b991dcd84e0 Will Deacon        2014-11-17  1290  				pass++;
fe4b991dcd84e0 Will Deacon        2014-11-17  1291  		}
fe4b991dcd84e0 Will Deacon        2014-11-17  1292  	}
fe4b991dcd84e0 Will Deacon        2014-11-17  1293  
fe4b991dcd84e0 Will Deacon        2014-11-17  1294  	pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail);
fe4b991dcd84e0 Will Deacon        2014-11-17  1295  	return fail ? -EFAULT : 0;
fe4b991dcd84e0 Will Deacon        2014-11-17 @1296  }
kernel test robot Feb. 1, 2023, 5:42 p.m. UTC | #2
Hi Byungchul,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tip/locking/core]
[also build test WARNING on tip/sched/core drm-misc/drm-misc-next linus/master v6.2-rc6 next-20230201]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Byungchul-Park/llist-Move-llist_-head-node-definition-to-types-h/20230131-164632
patch link:    https://lore.kernel.org/r/1675154394-25598-6-git-send-email-max.byungchul.park%40gmail.com
patch subject: [PATCH v9 05/25] dept: Tie to Lockdep and IRQ tracing
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20230202/202302020140.zbWuL7aK-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/ee619b0e7faff81e8b794e2adcdf9102d5bc83e8
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Byungchul-Park/llist-Move-llist_-head-node-definition-to-types-h/20230131-164632
        git checkout ee619b0e7faff81e8b794e2adcdf9102d5bc83e8
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 olddefconfig
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   vmlinux.o: warning: objtool: vmx_vcpu_enter_exit+0x164: call to context_tracking_guest_exit() leaves .noinstr.text section
   vmlinux.o: warning: objtool: svm_vcpu_enter_exit+0x85: call to context_tracking_guest_exit() leaves .noinstr.text section
   vmlinux.o: warning: objtool: do_machine_check+0xb1e: call to pentium_machine_check.constprop.0() leaves .noinstr.text section
>> vmlinux.o: warning: objtool: lockdep_hardirqs_on+0x12: call to dept_hardirqs_on_ip() leaves .noinstr.text section
>> vmlinux.o: warning: objtool: lockdep_hardirqs_off+0x9: call to dept_hardirqs_off_ip() leaves .noinstr.text section
   vmlinux.o: warning: objtool: lock_is_held_type+0x78: call to dept_hardirqs_off() leaves .noinstr.text section
   vmlinux.o: warning: objtool: irqentry_nmi_enter+0x14: call to dept_off() leaves .noinstr.text section
   vmlinux.o: warning: objtool: irqentry_nmi_exit+0x5a: call to dept_on() leaves .noinstr.text section
   vmlinux.o: warning: objtool: ct_idle_exit+0x40: call to dept_hardirqs_off() leaves .noinstr.text section
   vmlinux.o: warning: objtool: check_stackleak_irqoff+0x2b: call to end_of_stack.isra.0() leaves .noinstr.text section


objdump-func vmlinux.o lockdep_hardirqs_on:
0000 000000000000b980 <lockdep_hardirqs_on>:
0000     b980:	f3 0f 1e fa          	endbr64
0004     b984:	55                   	push   %rbp
0005     b985:	53                   	push   %rbx
0006     b986:	48 89 fb             	mov    %rdi,%rbx
0009     b989:	65 48 8b 2c 25 00 00 00 00 	mov    %gs:0x0,%rbp	b98e: R_X86_64_32S	pcpu_hot
0012     b992:	e8 00 00 00 00       	call   b997 <lockdep_hardirqs_on+0x17>	b993: R_X86_64_PLT32	dept_hardirqs_on_ip-0x4
0017     b997:	8b 3d 00 00 00 00    	mov    0x0(%rip),%edi        # b99d <lockdep_hardirqs_on+0x1d>	b999: R_X86_64_PC32	debug_locks-0x4
001d     b99d:	85 ff                	test   %edi,%edi
001f     b99f:	0f 84 cd 00 00 00    	je     ba72 <lockdep_hardirqs_on+0xf2>
0025     b9a5:	65 8b 05 00 00 00 00 	mov    %gs:0x0(%rip),%eax        # b9ac <lockdep_hardirqs_on+0x2c>	b9a8: R_X86_64_PC32	pcpu_hot+0x4
002c     b9ac:	a9 00 00 f0 00       	test   $0xf00000,%eax
0031     b9b1:	75 63                	jne    ba16 <lockdep_hardirqs_on+0x96>
0033     b9b3:	65 8b 05 00 00 00 00 	mov    %gs:0x0(%rip),%eax        # b9ba <lockdep_hardirqs_on+0x3a>	b9b6: R_X86_64_PC32	lockdep_recursion-0x4
003a     b9ba:	85 c0                	test   %eax,%eax
003c     b9bc:	0f 85 b0 00 00 00    	jne    ba72 <lockdep_hardirqs_on+0xf2>
0042     b9c2:	65 8b 05 00 00 00 00 	mov    %gs:0x0(%rip),%eax        # b9c9 <lockdep_hardirqs_on+0x49>	b9c5: R_X86_64_PC32	hardirqs_enabled-0x4
0049     b9c9:	85 c0                	test   %eax,%eax
004b     b9cb:	0f 85 b2 00 00 00    	jne    ba83 <lockdep_hardirqs_on+0x103>
0051     b9d1:	8b 35 00 00 00 00    	mov    0x0(%rip),%esi        # b9d7 <lockdep_hardirqs_on+0x57>	b9d3: R_X86_64_PC32	oops_in_progress-0x4
0057     b9d7:	85 f6                	test   %esi,%esi
0059     b9d9:	75 3b                	jne    ba16 <lockdep_hardirqs_on+0x96>
005b     b9db:	48 83 3d 00 00 00 00 00 	cmpq   $0x0,0x0(%rip)        # b9e3 <lockdep_hardirqs_on+0x63>	b9de: R_X86_64_PC32	pv_ops+0xeb
0063     b9e3:	0f 84 ed 00 00 00    	je     bad6 <lockdep_hardirqs_on+0x156>
0069     b9e9:	ff 15 00 00 00 00    	call   *0x0(%rip)        # b9ef <lockdep_hardirqs_on+0x6f>	b9eb: R_X86_64_PC32	pv_ops+0xec
006f     b9ef:	f6 c4 02             	test   $0x2,%ah
0072     b9f2:	0f 85 c1 00 00 00    	jne    bab9 <lockdep_hardirqs_on+0x139>
0078     b9f8:	8b 15 00 00 00 00    	mov    0x0(%rip),%edx        # b9fe <lockdep_hardirqs_on+0x7e>	b9fa: R_X86_64_PC32	oops_in_progress-0x4
007e     b9fe:	85 d2                	test   %edx,%edx
0080     ba00:	75 14                	jne    ba16 <lockdep_hardirqs_on+0x96>
0082     ba02:	48 8b 85 c8 0f 00 00 	mov    0xfc8(%rbp),%rax
0089     ba09:	48 39 85 f8 25 00 00 	cmp    %rax,0x25f8(%rbp)
0090     ba10:	0f 85 89 00 00 00    	jne    ba9f <lockdep_hardirqs_on+0x11f>
0096     ba16:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi	ba19: R_X86_64_32S	.rodata.str1.1+0x16d93
009d     ba1d:	e8 00 00 00 00       	call   ba22 <lockdep_hardirqs_on+0xa2>	ba1e: R_X86_64_PLT32	__this_cpu_preempt_check-0x4
00a2     ba22:	8b 85 b0 10 00 00    	mov    0x10b0(%rbp),%eax
00a8     ba28:	48 89 9d b8 10 00 00 	mov    %rbx,0x10b8(%rbp)
00af     ba2f:	65 c7 05 00 00 00 00 01 00 00 00 	movl   $0x1,%gs:0x0(%rip)        # ba3a <lockdep_hardirqs_on+0xba>	ba32: R_X86_64_PC32	hardirqs_enabled-0x8
00ba     ba3a:	83 c0 01             	add    $0x1,%eax
00bd     ba3d:	48 83 3d 00 00 00 00 00 	cmpq   $0x0,0x0(%rip)        # ba45 <lockdep_hardirqs_on+0xc5>	ba40: R_X86_64_PC32	pv_ops+0xeb
00c5     ba45:	89 85 b0 10 00 00    	mov    %eax,0x10b0(%rbp)
00cb     ba4b:	89 85 c8 10 00 00    	mov    %eax,0x10c8(%rbp)
00d1     ba51:	74 49                	je     ba9c <lockdep_hardirqs_on+0x11c>
00d3     ba53:	ff 15 00 00 00 00    	call   *0x0(%rip)        # ba59 <lockdep_hardirqs_on+0xd9>	ba55: R_X86_64_PC32	pv_ops+0xec
00d9     ba59:	f6 c4 02             	test   $0x2,%ah
00dc     ba5c:	75 72                	jne    bad0 <lockdep_hardirqs_on+0x150>
00de     ba5e:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi	ba61: R_X86_64_32S	.rodata.str1.1+0x16d99
00e5     ba65:	e8 00 00 00 00       	call   ba6a <lockdep_hardirqs_on+0xea>	ba66: R_X86_64_PLT32	__this_cpu_preempt_check-0x4
00ea     ba6a:	65 48 ff 05 00 00 00 00 	incq   %gs:0x0(%rip)        # ba72 <lockdep_hardirqs_on+0xf2>	ba6e: R_X86_64_PC32	lockdep_stats+0xc
00f2     ba72:	5b                   	pop    %rbx
00f3     ba73:	5d                   	pop    %rbp
00f4     ba74:	31 c0                	xor    %eax,%eax
00f6     ba76:	31 d2                	xor    %edx,%edx
00f8     ba78:	31 c9                	xor    %ecx,%ecx
00fa     ba7a:	31 f6                	xor    %esi,%esi
00fc     ba7c:	31 ff                	xor    %edi,%edi
00fe     ba7e:	e9 00 00 00 00       	jmp    ba83 <lockdep_hardirqs_on+0x103>	ba7f: R_X86_64_PLT32	__x86_return_thunk-0x4
0103     ba83:	65 48 ff 05 00 00 00 00 	incq   %gs:0x0(%rip)        # ba8b <lockdep_hardirqs_on+0x10b>	ba87: R_X86_64_PC32	lockdep_stats+0x1c
010b     ba8b:	5b                   	pop    %rbx
010c     ba8c:	5d                   	pop    %rbp
010d     ba8d:	31 c0                	xor    %eax,%eax
010f     ba8f:	31 d2                	xor    %edx,%edx
0111     ba91:	31 c9                	xor    %ecx,%ecx
0113     ba93:	31 f6                	xor    %esi,%esi
0115     ba95:	31 ff                	xor    %edi,%edi
0117     ba97:	e9 00 00 00 00       	jmp    ba9c <lockdep_hardirqs_on+0x11c>	ba98: R_X86_64_PLT32	__x86_return_thunk-0x4
011c     ba9c:	90                   	nop
011d     ba9d:	0f 0b                	ud2
011f     ba9f:	90                   	nop
0120     baa0:	e8 00 00 00 00       	call   baa5 <lockdep_hardirqs_on+0x125>	baa1: R_X86_64_PLT32	debug_locks_off-0x4
0125     baa5:	85 c0                	test   %eax,%eax
0127     baa7:	74 0a                	je     bab3 <lockdep_hardirqs_on+0x133>
0129     baa9:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # baaf <lockdep_hardirqs_on+0x12f>	baab: R_X86_64_PC32	debug_locks_silent-0x4
012f     baaf:	85 c0                	test   %eax,%eax
0131     bab1:	74 41                	je     baf4 <lockdep_hardirqs_on+0x174>
0133     bab3:	90                   	nop
0134     bab4:	e9 5d ff ff ff       	jmp    ba16 <lockdep_hardirqs_on+0x96>
0139     bab9:	90                   	nop
013a     baba:	e8 00 00 00 00       	call   babf <lockdep_hardirqs_on+0x13f>	babb: R_X86_64_PLT32	debug_locks_off-0x4
013f     babf:	85 c0                	test   %eax,%eax
0141     bac1:	74 0a                	je     bacd <lockdep_hardirqs_on+0x14d>
0143     bac3:	8b 0d 00 00 00 00    	mov    0x0(%rip),%ecx        # bac9 <lockdep_hardirqs_on+0x149>	bac5: R_X86_64_PC32	debug_locks_silent-0x4
0149     bac9:	85 c9                	test   %ecx,%ecx
014b     bacb:	74 0c                	je     bad9 <lockdep_hardirqs_on+0x159>
014d     bacd:	90                   	nop
014e     bace:	eb a2                	jmp    ba72 <lockdep_hardirqs_on+0xf2>
0150     bad0:	90                   	nop
0151     bad1:	0f 0b                	ud2
0153     bad3:	90                   	nop
0154     bad4:	eb 88                	jmp    ba5e <lockdep_hardirqs_on+0xde>
0156     bad6:	90                   	nop
0157     bad7:	0f 0b                	ud2
0159     bad9:	90                   	nop
015a     bada:	48 c7 c6 00 00 00 00 	mov    $0x0,%rsi	badd: R_X86_64_32S	.rodata.str1.1+0x16d82
0161     bae1:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi	bae4: R_X86_64_32S	.rodata.str1.1+0x16d41
0168     bae8:	e8 00 00 00 00       	call   baed <lockdep_hardirqs_on+0x16d>	bae9: R_X86_64_PLT32	__warn_printk-0x4
016d     baed:	90                   	nop
016e     baee:	0f 0b                	ud2
0170     baf0:	90                   	nop
0171     baf1:	90                   	nop
0172     baf2:	eb d9                	jmp    bacd <lockdep_hardirqs_on+0x14d>
0174     baf4:	90                   	nop
0175     baf5:	48 c7 c6 00 00 00 00 	mov    $0x0,%rsi	baf8: R_X86_64_32S	.rodata.str1.8+0x2f280
017c     bafc:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi	baff: R_X86_64_32S	.rodata.str1.1+0x16d41
0183     bb03:	e8 00 00 00 00       	call   bb08 <lockdep_hardirqs_on+0x188>	bb04: R_X86_64_PLT32	__warn_printk-0x4
0188     bb08:	90                   	nop
0189     bb09:	0f 0b                	ud2
018b     bb0b:	90                   	nop
018c     bb0c:	90                   	nop
018d     bb0d:	eb a4                	jmp    bab3 <lockdep_hardirqs_on+0x133>
018f     bb0f:	66 66 2e 0f 1f 84 00 00 00 00 00 	data16 cs nopw 0x0(%rax,%rax,1)
019a     bb1a:	66 66 2e 0f 1f 84 00 00 00 00 00 	data16 cs nopw 0x0(%rax,%rax,1)
01a5     bb25:	66 66 2e 0f 1f 84 00 00 00 00 00 	data16 cs nopw 0x0(%rax,%rax,1)
01b0     bb30:	66 66 2e 0f 1f 84 00 00 00 00 00 	data16 cs nopw 0x0(%rax,%rax,1)
01bb     bb3b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
diff mbox series

Patch

diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 5ec0fa7..0ebc5ec 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -13,6 +13,7 @@ 
 #define _LINUX_TRACE_IRQFLAGS_H
 
 #include <linux/typecheck.h>
+#include <linux/dept.h>
 #include <asm/irqflags.h>
 #include <asm/percpu.h>
 
@@ -60,8 +61,10 @@  struct irqtrace_events {
 # define lockdep_softirqs_enabled(p)	((p)->softirqs_enabled)
 # define lockdep_hardirq_enter()			\
 do {							\
-	if (__this_cpu_inc_return(hardirq_context) == 1)\
+	if (__this_cpu_inc_return(hardirq_context) == 1) { \
 		current->hardirq_threaded = 0;		\
+		dept_hardirq_enter();			\
+	}						\
 } while (0)
 # define lockdep_hardirq_threaded()		\
 do {						\
@@ -136,6 +139,8 @@  struct irqtrace_events {
 # define lockdep_softirq_enter()		\
 do {						\
 	current->softirq_context++;		\
+	if (current->softirq_context == 1)	\
+		dept_softirq_enter();		\
 } while (0)
 # define lockdep_softirq_exit()			\
 do {						\
@@ -170,17 +175,28 @@  struct irqtrace_events {
 /*
  * Wrap the arch provided IRQ routines to provide appropriate checks.
  */
-#define raw_local_irq_disable()		arch_local_irq_disable()
-#define raw_local_irq_enable()		arch_local_irq_enable()
+#define raw_local_irq_disable()				\
+	do {						\
+		arch_local_irq_disable();		\
+		dept_hardirqs_off();			\
+	} while (0)
+#define raw_local_irq_enable()				\
+	do {						\
+		dept_hardirqs_on();			\
+		arch_local_irq_enable();		\
+	} while (0)
 #define raw_local_irq_save(flags)			\
 	do {						\
 		typecheck(unsigned long, flags);	\
 		flags = arch_local_irq_save();		\
+		dept_hardirqs_off();			\
 	} while (0)
 #define raw_local_irq_restore(flags)			\
 	do {						\
 		typecheck(unsigned long, flags);	\
 		raw_check_bogus_irq_restore();		\
+		if (!arch_irqs_disabled_flags(flags))	\
+			dept_hardirqs_on();		\
 		arch_local_irq_restore(flags);		\
 	} while (0)
 #define raw_local_save_flags(flags)			\
diff --git a/include/linux/local_lock_internal.h b/include/linux/local_lock_internal.h
index 975e33b..39f6778 100644
--- a/include/linux/local_lock_internal.h
+++ b/include/linux/local_lock_internal.h
@@ -21,6 +21,7 @@ 
 		.name = #lockname,			\
 		.wait_type_inner = LD_WAIT_CONFIG,	\
 		.lock_type = LD_LOCK_PERCPU,		\
+		.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
 	},						\
 	.owner = NULL,
 
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 1f1099d..9996102 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -12,6 +12,7 @@ 
 
 #include <linux/lockdep_types.h>
 #include <linux/smp.h>
+#include <linux/dept_ldt.h>
 #include <asm/percpu.h>
 
 struct task_struct;
@@ -39,6 +40,8 @@  static inline void lockdep_copy_map(struct lockdep_map *to,
 	 */
 	for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++)
 		to->class_cache[i] = NULL;
+
+	dept_map_copy(&to->dmap, &from->dmap);
 }
 
 /*
@@ -441,7 +444,8 @@  enum xhlock_context_t {
  * Note that _name must not be NULL.
  */
 #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
-	{ .name = (_name), .key = (void *)(_key), }
+	{ .name = (_name), .key = (void *)(_key), \
+	  .dmap = DEPT_MAP_INITIALIZER(_name, _key) }
 
 static inline void lockdep_invariant_state(bool force) {}
 static inline void lockdep_free_task(struct task_struct *task) {}
@@ -523,33 +527,89 @@  static inline void print_irqtrace_events(struct task_struct *curr)
 #define lock_acquire_shared(l, s, t, n, i)		lock_acquire(l, s, t, 1, 1, n, i)
 #define lock_acquire_shared_recursive(l, s, t, n, i)	lock_acquire(l, s, t, 2, 1, n, i)
 
-#define spin_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
-#define spin_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
-#define spin_release(l, i)			lock_release(l, i)
-
-#define rwlock_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
+#define spin_acquire(l, s, t, i)					\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, NULL, i);				\
+	lock_acquire_exclusive(l, s, t, NULL, i);			\
+} while (0)
+#define spin_acquire_nest(l, s, t, n, i)				\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, n, i);				\
+	lock_acquire_exclusive(l, s, t, n, i);				\
+} while (0)
+#define spin_release(l, i)						\
+do {									\
+	ldt_unlock(&(l)->dmap, i);					\
+	lock_release(l, i);						\
+} while (0)
+#define rwlock_acquire(l, s, t, i)					\
+do {									\
+	ldt_wlock(&(l)->dmap, s, t, NULL, i);				\
+	lock_acquire_exclusive(l, s, t, NULL, i);			\
+} while (0)
 #define rwlock_acquire_read(l, s, t, i)					\
 do {									\
+	ldt_rlock(&(l)->dmap, s, t, NULL, i, !read_lock_is_recursive());\
 	if (read_lock_is_recursive())					\
 		lock_acquire_shared_recursive(l, s, t, NULL, i);	\
 	else								\
 		lock_acquire_shared(l, s, t, NULL, i);			\
 } while (0)
-
-#define rwlock_release(l, i)			lock_release(l, i)
-
-#define seqcount_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
-#define seqcount_acquire_read(l, s, t, i)	lock_acquire_shared_recursive(l, s, t, NULL, i)
-#define seqcount_release(l, i)			lock_release(l, i)
-
-#define mutex_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
-#define mutex_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
-#define mutex_release(l, i)			lock_release(l, i)
-
-#define rwsem_acquire(l, s, t, i)		lock_acquire_exclusive(l, s, t, NULL, i)
-#define rwsem_acquire_nest(l, s, t, n, i)	lock_acquire_exclusive(l, s, t, n, i)
-#define rwsem_acquire_read(l, s, t, i)		lock_acquire_shared(l, s, t, NULL, i)
-#define rwsem_release(l, i)			lock_release(l, i)
+#define rwlock_release(l, i)						\
+do {									\
+	ldt_unlock(&(l)->dmap, i);					\
+	lock_release(l, i);						\
+} while (0)
+#define seqcount_acquire(l, s, t, i)					\
+do {									\
+	ldt_wlock(&(l)->dmap, s, t, NULL, i);				\
+	lock_acquire_exclusive(l, s, t, NULL, i);			\
+} while (0)
+#define seqcount_acquire_read(l, s, t, i)				\
+do {									\
+	ldt_rlock(&(l)->dmap, s, t, NULL, i, false);			\
+	lock_acquire_shared_recursive(l, s, t, NULL, i);		\
+} while (0)
+#define seqcount_release(l, i)						\
+do {									\
+	ldt_unlock(&(l)->dmap, i);					\
+	lock_release(l, i);						\
+} while (0)
+#define mutex_acquire(l, s, t, i)					\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, NULL, i);				\
+	lock_acquire_exclusive(l, s, t, NULL, i);			\
+} while (0)
+#define mutex_acquire_nest(l, s, t, n, i)				\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, n, i);				\
+	lock_acquire_exclusive(l, s, t, n, i);				\
+} while (0)
+#define mutex_release(l, i)						\
+do {									\
+	ldt_unlock(&(l)->dmap, i);					\
+	lock_release(l, i);						\
+} while (0)
+#define rwsem_acquire(l, s, t, i)					\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, NULL, i);				\
+	lock_acquire_exclusive(l, s, t, NULL, i);			\
+} while (0)
+#define rwsem_acquire_nest(l, s, t, n, i)				\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, n, i);				\
+	lock_acquire_exclusive(l, s, t, n, i);				\
+} while (0)
+#define rwsem_acquire_read(l, s, t, i)					\
+do {									\
+	ldt_lock(&(l)->dmap, s, t, NULL, i);				\
+	lock_acquire_shared(l, s, t, NULL, i);				\
+} while (0)
+#define rwsem_release(l, i)						\
+do {									\
+	ldt_unlock(&(l)->dmap, i);					\
+	lock_release(l, i);						\
+} while (0)
 
 #define lock_map_acquire(l)			lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_)
 #define lock_map_acquire_read(l)		lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
diff --git a/include/linux/lockdep_types.h b/include/linux/lockdep_types.h
index d224308..50c8879 100644
--- a/include/linux/lockdep_types.h
+++ b/include/linux/lockdep_types.h
@@ -11,6 +11,7 @@ 
 #define __LINUX_LOCKDEP_TYPES_H
 
 #include <linux/types.h>
+#include <linux/dept.h>
 
 #define MAX_LOCKDEP_SUBCLASSES		8UL
 
@@ -76,6 +77,7 @@  struct lock_class_key {
 		struct hlist_node		hash_entry;
 		struct lockdep_subclass_key	subkeys[MAX_LOCKDEP_SUBCLASSES];
 	};
+	struct dept_key				dkey;
 };
 
 extern struct lock_class_key __lockdep_no_validate__;
@@ -185,6 +187,7 @@  struct lockdep_map {
 	int				cpu;
 	unsigned long			ip;
 #endif
+	struct dept_map			dmap;
 };
 
 struct pin_cookie { unsigned int val; };
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 8f226d4..58bf314 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -25,6 +25,7 @@ 
 		, .dep_map = {					\
 			.name = #lockname,			\
 			.wait_type_inner = LD_WAIT_SLEEP,	\
+			.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
 		}
 #else
 # define __DEP_MAP_MUTEX_INITIALIZER(lockname)
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
index 36b942b..e871aca 100644
--- a/include/linux/percpu-rwsem.h
+++ b/include/linux/percpu-rwsem.h
@@ -21,7 +21,7 @@  struct percpu_rw_semaphore {
 };
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-#define __PERCPU_RWSEM_DEP_MAP_INIT(lockname)	.dep_map = { .name = #lockname },
+#define __PERCPU_RWSEM_DEP_MAP_INIT(lockname)	.dep_map = { .name = #lockname, .dmap = DEPT_MAP_INITIALIZER(lockname, NULL) },
 #else
 #define __PERCPU_RWSEM_DEP_MAP_INIT(lockname)
 #endif
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h
index 7d04988..35889ac 100644
--- a/include/linux/rtmutex.h
+++ b/include/linux/rtmutex.h
@@ -81,6 +81,7 @@  static inline void rt_mutex_debug_task_free(struct task_struct *tsk) { }
 	.dep_map = {					\
 		.name = #mutexname,			\
 		.wait_type_inner = LD_WAIT_SLEEP,	\
+		.dmap = DEPT_MAP_INITIALIZER(mutexname, NULL),\
 	}
 #else
 #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)
diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h
index 1948442..6e58dfc 100644
--- a/include/linux/rwlock_types.h
+++ b/include/linux/rwlock_types.h
@@ -10,6 +10,7 @@ 
 	.dep_map = {							\
 		.name = #lockname,					\
 		.wait_type_inner = LD_WAIT_CONFIG,			\
+		.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),		\
 	}
 #else
 # define RW_DEP_MAP_INIT(lockname)
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
index efa5c32..4f856e7 100644
--- a/include/linux/rwsem.h
+++ b/include/linux/rwsem.h
@@ -21,6 +21,7 @@ 
 	.dep_map = {					\
 		.name = #lockname,			\
 		.wait_type_inner = LD_WAIT_SLEEP,	\
+		.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
 	},
 #else
 # define __RWSEM_DEP_MAP_INIT(lockname)
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 3926e90..6ba00bc 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -81,7 +81,7 @@  static inline void __seqcount_init(seqcount_t *s, const char *name,
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
 # define SEQCOUNT_DEP_MAP_INIT(lockname)				\
-		.dep_map = { .name = #lockname }
+		.dep_map = { .name = #lockname, .dmap = DEPT_MAP_INITIALIZER(lockname, NULL) }
 
 /**
  * seqcount_init() - runtime initializer for seqcount_t
diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_types_raw.h
index 91cb36b..3dcc551 100644
--- a/include/linux/spinlock_types_raw.h
+++ b/include/linux/spinlock_types_raw.h
@@ -31,11 +31,13 @@ 
 	.dep_map = {					\
 		.name = #lockname,			\
 		.wait_type_inner = LD_WAIT_SPIN,	\
+		.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
 	}
 # define SPIN_DEP_MAP_INIT(lockname)			\
 	.dep_map = {					\
 		.name = #lockname,			\
 		.wait_type_inner = LD_WAIT_CONFIG,	\
+		.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
 	}
 
 # define LOCAL_SPIN_DEP_MAP_INIT(lockname)		\
@@ -43,6 +45,7 @@ 
 		.name = #lockname,			\
 		.wait_type_inner = LD_WAIT_CONFIG,	\
 		.lock_type = LD_LOCK_PERCPU,		\
+		.dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
 	}
 #else
 # define RAW_SPIN_DEP_MAP_INIT(lockname)
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 9b9d0bb..c934158 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -35,7 +35,7 @@  int __init_srcu_struct(struct srcu_struct *ssp, const char *name,
 	__init_srcu_struct((ssp), #ssp, &__srcu_key); \
 })
 
-#define __SRCU_DEP_MAP_INIT(srcu_name)	.dep_map = { .name = #srcu_name },
+#define __SRCU_DEP_MAP_INIT(srcu_name)	.dep_map = { .name = #srcu_name, .dmap = DEPT_MAP_INITIALIZER(srcu_name, NULL) },
 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 int init_srcu_struct(struct srcu_struct *ssp);
diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index 03d82e9..c92fe94 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -245,10 +245,10 @@  static inline bool dept_working(void)
  * Even k == NULL is considered as a valid key because it would use
  * &->map_key as the key in that case.
  */
-struct dept_key __dept_no_validate__;
+extern struct lock_class_key __lockdep_no_validate__;
 static inline bool valid_key(struct dept_key *k)
 {
-	return &__dept_no_validate__ != k;
+	return &__lockdep_no_validate__.dkey != k;
 }
 
 /*
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e3375bc..7ff3fb4 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1220,6 +1220,8 @@  void lockdep_register_key(struct lock_class_key *key)
 	struct lock_class_key *k;
 	unsigned long flags;
 
+	dept_key_init(&key->dkey);
+
 	if (WARN_ON_ONCE(static_obj(key)))
 		return;
 	hash_head = keyhashentry(key);
@@ -4327,6 +4329,8 @@  void noinstr lockdep_hardirqs_on(unsigned long ip)
 {
 	struct irqtrace_events *trace = &current->irqtrace;
 
+	dept_hardirqs_on_ip(ip);
+
 	if (unlikely(!debug_locks))
 		return;
 
@@ -4392,6 +4396,8 @@  void noinstr lockdep_hardirqs_on(unsigned long ip)
  */
 void noinstr lockdep_hardirqs_off(unsigned long ip)
 {
+	dept_hardirqs_off_ip(ip);
+
 	if (unlikely(!debug_locks))
 		return;
 
@@ -4436,6 +4442,8 @@  void lockdep_softirqs_on(unsigned long ip)
 {
 	struct irqtrace_events *trace = &current->irqtrace;
 
+	dept_softirqs_on_ip(ip);
+
 	if (unlikely(!lockdep_enabled()))
 		return;
 
@@ -4474,6 +4482,9 @@  void lockdep_softirqs_on(unsigned long ip)
  */
 void lockdep_softirqs_off(unsigned long ip)
 {
+
+	dept_softirqs_off_ip(ip);
+
 	if (unlikely(!lockdep_enabled()))
 		return;
 
@@ -4806,6 +4817,8 @@  void lockdep_init_map_type(struct lockdep_map *lock, const char *name,
 {
 	int i;
 
+	ldt_init(&lock->dmap, &key->dkey, subclass, name);
+
 	for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++)
 		lock->class_cache[i] = NULL;
 
@@ -5544,6 +5557,12 @@  void lock_set_class(struct lockdep_map *lock, const char *name,
 {
 	unsigned long flags;
 
+	/*
+	 * dept_map_(re)init() might be called twice redundantly. But
+	 * there's no choice as long as Dept relies on Lockdep.
+	 */
+	ldt_set_class(&lock->dmap, name, &key->dkey, subclass, ip);
+
 	if (unlikely(!lockdep_enabled()))
 		return;
 
@@ -5561,6 +5580,8 @@  void lock_downgrade(struct lockdep_map *lock, unsigned long ip)
 {
 	unsigned long flags;
 
+	ldt_downgrade(&lock->dmap, ip);
+
 	if (unlikely(!lockdep_enabled()))
 		return;
 
@@ -6333,6 +6354,8 @@  void lockdep_unregister_key(struct lock_class_key *key)
 	unsigned long flags;
 	bool found = false;
 
+	dept_key_destroy(&key->dkey);
+
 	might_sleep();
 
 	if (WARN_ON_ONCE(static_obj(key)))