diff mbox series

[v2] scsi: stop judging after finding a VPD page expected to be processed.

Message ID 20250227060618.15787-1-wdhh6@aliyun.com (mailing list archive)
State Rejected
Headers show
Series [v2] scsi: stop judging after finding a VPD page expected to be processed. | expand

Commit Message

Chaohai Chen Feb. 27, 2025, 6:06 a.m. UTC
When the vpd_buf->data[i] is expected to be processed, stop other
judgments.

Signed-off-by: Chaohai Chen <wdhh6@aliyun.com>
---
v1: https://lore.kernel.org/all/20250226065802.234144-1-wdhh6@aliyun.com/
v1->v2:
 * Modify this function so that there is no code duplication
---
---
 drivers/scsi/scsi.c        | 39 +++++++++++++++++++++-----------------
 include/scsi/scsi_device.h | 12 ++++++++++++
 2 files changed, 34 insertions(+), 17 deletions(-)

Comments

John Garry Feb. 27, 2025, 7:55 a.m. UTC | #1
On 27/02/2025 06:06, Chaohai Chen wrote:
> +#define SCSI_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - sizeof(char))
> +
> +#define VPD_PAGE_INFO(vpd_page)							\
> +	{ 0x##vpd_page, offsetof(struct scsi_device, vpd_pg##vpd_page) + \
> +		SCSI_BUILD_BUG_ON(!__same_type(&((struct scsi_device *)NULL)->vpd_pg##vpd_page, \
> +				struct scsi_vpd __rcu **))} \
> +
>   #define	to_scsi_device(d)	\

That's unreadable....
kernel test robot March 4, 2025, 5:04 a.m. UTC | #2
Hello,

kernel test robot noticed "BUG:unable_to_handle_page_fault_for_address" on:

commit: 8e44a5176a631b6b5ba7efa557d8b1895eb56d85 ("[PATCH v2] scsi: stop judging after finding a VPD page expected to be processed.")
url: https://github.com/intel-lab-lkp/linux/commits/Chaohai-Chen/scsi-stop-judging-after-finding-a-VPD-page-expected-to-be-processed/20250227-140720
base: https://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git for-next
patch link: https://lore.kernel.org/all/20250227060618.15787-1-wdhh6@aliyun.com/
patch subject: [PATCH v2] scsi: stop judging after finding a VPD page expected to be processed.

in testcase: boot

config: x86_64-rhel-9.4
compiler: gcc-12
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+---------------------------------------------+------------+------------+
|                                             | 5d51aea463 | 8e44a5176a |
+---------------------------------------------+------------+------------+
| boot_successes                              | 12         | 0          |
| boot_failures                               | 0          | 14         |
| BUG:unable_to_handle_page_fault_for_address | 0          | 14         |
| Oops                                        | 0          | 14         |
| RIP:build_detached_freelist                 | 0          | 14         |
| Kernel_panic-not_syncing:Fatal_exception    | 0          | 14         |
+---------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202503041036.ad427cb-lkp@intel.com


[   14.245211][  T124] BUG: unable to handle page fault for address: ffffdeda9e000008
[   14.245852][  T124] #PF: supervisor read access in kernel mode
[   14.246293][  T124] #PF: error_code(0x0000) - not-present page
[   14.246740][  T124] PGD 0 P4D 0
[   14.247003][  T124] Oops: Oops: 0000 [#1] SMP PTI
[   14.247375][  T124] CPU: 1 UID: 0 PID: 124 Comm: kworker/u8:3 Not tainted 6.14.0-rc1-00076-g8e44a5176a63 #1
[   14.248100][  T124] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   14.248837][  T124] Workqueue: events_unbound kfree_rcu_work
[ 14.249283][ T124] RIP: 0010:build_detached_freelist (include/linux/page-flags.h:243 include/linux/mm.h:1297 mm/slab.h:211 mm/slub.c:4941) 
[ 14.250299][ T124] Code: 8b 03 48 89 ca 48 01 c2 0f 82 ed 01 00 00 4d 89 d3 4c 2b 1d 74 b4 57 01 4c 01 da 48 c1 ea 0c 48 c1 e2 06 48 03 15 52 b4 57 01 <4c> 8b 6a 08 49 89 d3 41 f6 c5 01 0f 85 dd 00 00 00 0f 1f 44 00 00
All code
========
   0:	8b 03                	mov    (%rbx),%eax
   2:	48 89 ca             	mov    %rcx,%rdx
   5:	48 01 c2             	add    %rax,%rdx
   8:	0f 82 ed 01 00 00    	jb     0x1fb
   e:	4d 89 d3             	mov    %r10,%r11
  11:	4c 2b 1d 74 b4 57 01 	sub    0x157b474(%rip),%r11        # 0x157b48c
  18:	4c 01 da             	add    %r11,%rdx
  1b:	48 c1 ea 0c          	shr    $0xc,%rdx
  1f:	48 c1 e2 06          	shl    $0x6,%rdx
  23:	48 03 15 52 b4 57 01 	add    0x157b452(%rip),%rdx        # 0x157b47c
  2a:*	4c 8b 6a 08          	mov    0x8(%rdx),%r13		<-- trapping instruction
  2e:	49 89 d3             	mov    %rdx,%r11
  31:	41 f6 c5 01          	test   $0x1,%r13b
  35:	0f 85 dd 00 00 00    	jne    0x118
  3b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Code starting with the faulting instruction
===========================================
   0:	4c 8b 6a 08          	mov    0x8(%rdx),%r13
   4:	49 89 d3             	mov    %rdx,%r11
   7:	41 f6 c5 01          	test   $0x1,%r13b
   b:	0f 85 dd 00 00 00    	jne    0xee
  11:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
[   14.252909][  T124] RSP: 0000:ffffa8e5004ebcd0 EFLAGS: 00010286
[   14.253973][  T124] RAX: 0000000080000000 RBX: ffffa8e5004ebd50 RCX: 0000000000000003
[   14.255143][  T124] RDX: ffffdeda9e000000 RSI: 0000000000000177 RDI: 0000000000000002
[   14.256313][  T124] RBP: ffff95f9e637b028 R08: ffffdd3284e15900 R09: 0000000000000000
[   14.257464][  T124] R10: ffffffff80000000 R11: 00006a0700000000 R12: 0000000000000178
[   14.258661][  T124] R13: 504d56b8f995ffff R14: ffff95f980042200 R15: 000000000000017d
[   14.259806][  T124] FS:  0000000000000000(0000) GS:ffff95fcafd00000(0000) knlGS:0000000000000000
[   14.261074][  T124] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   14.262173][  T124] CR2: ffffdeda9e000008 CR3: 0000000167df6000 CR4: 00000000000406f0
[   14.263363][  T124] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   14.264575][  T124] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   14.265747][  T124] Call Trace:
[   14.266530][  T124]  <TASK>
[ 14.267349][ T124] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434) 
[ 14.268182][ T124] ? page_fault_oops (arch/x86/mm/fault.c:714) 
[ 14.269105][ T124] ? exc_page_fault (arch/x86/mm/fault.c:1478 arch/x86/mm/fault.c:1538) 
[ 14.269972][ T124] ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:623) 
[ 14.270888][ T124] ? build_detached_freelist (include/linux/page-flags.h:243 include/linux/mm.h:1297 mm/slab.h:211 mm/slub.c:4941) 
[ 14.271810][ T124] kmem_cache_free_bulk (mm/slub.c:4706) 
[ 14.272840][ T124] ? dequeue_entity (kernel/sched/fair.c:5488) 
[ 14.273683][ T124] ? kvfree_rcu_bulk (include/linux/slab.h:791 mm/slab_common.c:1498) 
[ 14.274542][ T124] kvfree_rcu_bulk (include/linux/slab.h:791 mm/slab_common.c:1498) 
[ 14.275389][ T124] kfree_rcu_work (mm/slab_common.c:1576) 
[ 14.276255][ T124] ? finish_task_switch+0x85/0x2b0 
[ 14.277161][ T124] process_one_work (kernel/workqueue.c:3241) 
[ 14.277998][ T124] worker_thread (kernel/workqueue.c:3311 kernel/workqueue.c:3398) 
[ 14.278830][ T124] ? __pfx_worker_thread (kernel/workqueue.c:3344) 
[ 14.279670][ T124] kthread (kernel/kthread.c:464) 
[ 14.280456][ T124] ? __pfx_kthread (kernel/kthread.c:413) 
[ 14.281263][ T124] ret_from_fork (arch/x86/kernel/process.c:154) 
[ 14.282106][ T124] ? __pfx_kthread (kernel/kthread.c:413) 
[ 14.282915][ T124] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[   14.283726][  T124]  </TASK>
[   14.284397][  T124] Modules linked in: ipmi_devintf ipmi_msghandler sr_mod cdrom sg snd_pcm intel_rapl_msr ata_generic intel_rapl_common snd_timer ghash_clmulni_intel ppdev rapl snd bochs drm_client_lib drm_shmem_helper soundcore i2c_piix4 ata_piix i2c_smbus drm_kms_helper joydev pcspkr parport_pc libata serio_raw parport fuse drm ip_tables
[   14.287967][  T124] CR2: ffffdeda9e000008
[   14.288794][  T124] ---[ end trace 0000000000000000 ]---
[ 14.289744][ T124] RIP: 0010:build_detached_freelist (include/linux/page-flags.h:243 include/linux/mm.h:1297 mm/slab.h:211 mm/slub.c:4941) 
[ 14.290724][ T124] Code: 8b 03 48 89 ca 48 01 c2 0f 82 ed 01 00 00 4d 89 d3 4c 2b 1d 74 b4 57 01 4c 01 da 48 c1 ea 0c 48 c1 e2 06 48 03 15 52 b4 57 01 <4c> 8b 6a 08 49 89 d3 41 f6 c5 01 0f 85 dd 00 00 00 0f 1f 44 00 00
All code
========
   0:	8b 03                	mov    (%rbx),%eax
   2:	48 89 ca             	mov    %rcx,%rdx
   5:	48 01 c2             	add    %rax,%rdx
   8:	0f 82 ed 01 00 00    	jb     0x1fb
   e:	4d 89 d3             	mov    %r10,%r11
  11:	4c 2b 1d 74 b4 57 01 	sub    0x157b474(%rip),%r11        # 0x157b48c
  18:	4c 01 da             	add    %r11,%rdx
  1b:	48 c1 ea 0c          	shr    $0xc,%rdx
  1f:	48 c1 e2 06          	shl    $0x6,%rdx
  23:	48 03 15 52 b4 57 01 	add    0x157b452(%rip),%rdx        # 0x157b47c
  2a:*	4c 8b 6a 08          	mov    0x8(%rdx),%r13		<-- trapping instruction
  2e:	49 89 d3             	mov    %rdx,%r11
  31:	41 f6 c5 01          	test   $0x1,%r13b
  35:	0f 85 dd 00 00 00    	jne    0x118
  3b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Code starting with the faulting instruction
===========================================
   0:	4c 8b 6a 08          	mov    0x8(%rdx),%r13
   4:	49 89 d3             	mov    %rdx,%r11
   7:	41 f6 c5 01          	test   $0x1,%r13b
   b:	0f 85 dd 00 00 00    	jne    0xee
  11:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20250304/202503041036.ad427cb-lkp@intel.com
diff mbox series

Patch

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a77e0499b738..e840616d4deb 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -498,8 +498,18 @@  static void scsi_update_vpd_page(struct scsi_device *sdev, u8 page,
  */
 void scsi_attach_vpd(struct scsi_device *sdev)
 {
-	int i;
+	int i, j;
 	struct scsi_vpd *vpd_buf;
+	static const struct vpd_page_info cached_page[] = {
+		VPD_PAGE_INFO(0),
+		VPD_PAGE_INFO(80),
+		VPD_PAGE_INFO(83),
+		VPD_PAGE_INFO(89),
+		VPD_PAGE_INFO(b0),
+		VPD_PAGE_INFO(b1),
+		VPD_PAGE_INFO(b2),
+		VPD_PAGE_INFO(b7),
+	};
 
 	if (!scsi_device_supports_vpd(sdev))
 		return;
@@ -510,22 +520,17 @@  void scsi_attach_vpd(struct scsi_device *sdev)
 		return;
 
 	for (i = 4; i < vpd_buf->len; i++) {
-		if (vpd_buf->data[i] == 0x0)
-			scsi_update_vpd_page(sdev, 0x0, &sdev->vpd_pg0);
-		if (vpd_buf->data[i] == 0x80)
-			scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80);
-		if (vpd_buf->data[i] == 0x83)
-			scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83);
-		if (vpd_buf->data[i] == 0x89)
-			scsi_update_vpd_page(sdev, 0x89, &sdev->vpd_pg89);
-		if (vpd_buf->data[i] == 0xb0)
-			scsi_update_vpd_page(sdev, 0xb0, &sdev->vpd_pgb0);
-		if (vpd_buf->data[i] == 0xb1)
-			scsi_update_vpd_page(sdev, 0xb1, &sdev->vpd_pgb1);
-		if (vpd_buf->data[i] == 0xb2)
-			scsi_update_vpd_page(sdev, 0xb2, &sdev->vpd_pgb2);
-		if (vpd_buf->data[i] == 0xb7)
-			scsi_update_vpd_page(sdev, 0xb7, &sdev->vpd_pgb7);
+		for (j = 0; j < ARRAY_SIZE(cached_page); j++) {
+			const u8 page_code = cached_page[j].page_code;
+			const u16 offset = cached_page[j].offset;
+			struct scsi_vpd __rcu **vpd_data =
+				(void *)&sdev + offset;
+
+			if (vpd_buf->data[i] == page_code) {
+				scsi_update_vpd_page(sdev, page_code, vpd_data);
+				break;
+			}
+		}
 	}
 	kfree(vpd_buf);
 }
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 7acd0ec82bb0..46f17875b758 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -284,6 +284,18 @@  struct scsi_device {
 	unsigned long		sdev_data[];
 } __attribute__((aligned(sizeof(unsigned long))));
 
+struct vpd_page_info {
+	u8 page_code;
+	u16 offset; /* offset in struct scsi_device of vpd_pg... member */
+};
+
+#define SCSI_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - sizeof(char))
+
+#define VPD_PAGE_INFO(vpd_page)							\
+	{ 0x##vpd_page, offsetof(struct scsi_device, vpd_pg##vpd_page) + \
+		SCSI_BUILD_BUG_ON(!__same_type(&((struct scsi_device *)NULL)->vpd_pg##vpd_page, \
+				struct scsi_vpd __rcu **))} \
+
 #define	to_scsi_device(d)	\
 	container_of(d, struct scsi_device, sdev_gendev)
 #define	class_to_sdev(d)	\