[PATCH V2 1/2] nvme-core: replace ctrl page size with a macro

Keith Busch kbusch at kernel.org
Fri Jul 10 10:57:42 EDT 2020


On Thu, Jul 09, 2020 at 04:40:24PM -0700, Chaitanya Kulkarni wrote:
> When nvme_pci_iod_alloc_size() is called with false as last argument it
> results in following oops since dev->ctrl.page_size used before we set
> it in the nvme_enable_ctrl() in above path :-
> 
> Entering kdb (current=0xffff88881fc0c980, pid 339) on processor 0 Oops: (null)
> due to oops @ 0xffffffffa05f1723
> CPU: 0 PID: 339 Comm: kworker/0:2 Tainted: G        W  OE     5.8.0-rc1nvme-5.9+ #20
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.4Workqueue: events work_for_cpu_fn
> RIP: 0010:nvme_probe+0x263/0x502 [nvme]
> Code: 00 00 66 41 81 7c 24 3c 4d 14 0f 84 98 01 00 00 3d 0f 1e 01 00 0f 84 aa 01 00 00 8b 8b a0 0c 00 2
> RSP: 0018:ffffc90000d9bdd8 EFLAGS: 00010246
> RAX: 0000000000000fff RBX: ffff8887da128000 RCX: 0000000000000000
> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000246
> RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: ffff8887c29f5570 R12: ffff888813c37000
> R13: 0000000000000202 R14: 0000000fffffffe0 R15: ffff888813c370b0
> FS:  0000000000000000(0000) GS:ffff88880fe00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007f23185131a0 CR3: 0000000811c54000 CR4: 00000000003406f0
> Call Trace:
>  local_pci_probe+0x42/0x80
>  work_for_cpu_fn+0x16/0x20
>  process_one_work+0x24e/0x5a0
>  ? __schedule+0x353/0x840
>  worker_thread+0x1d5/0x380
>  ? process_one_work+0x5a0/0x5a0
>  kthread+0x135/0x150
>  ? kthread_create_on_node+0x60/0x60
>  ret_from_fork+0x22/0x30
> 
> This patch removes the dev->ctrl.page_size variable and replaces with
> the macro which avoids above oops

This makes it sound like we'd actually trigger this bug, but we
currently don't do that. I think the changelog should be more about why
we can remove of 'ctrl->page_size', something like:

  Saving the nvme controller's page size was from a time when the driver
  tried to use different sized pages, but this value is always set to
  a constant, and has been this way for some time. Remove the
  'page_size' field and replace its usage with the constant value.

This also lets the compiler make some micro-optimizations in the io
path, and that's always a good thing.


> @@ -1825,7 +1824,7 @@ static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
>  	c.features.fid		= cpu_to_le32(NVME_FEAT_HOST_MEM_BUF);
>  	c.features.dword11	= cpu_to_le32(bits);
>  	c.features.dword12	= cpu_to_le32(dev->host_mem_size >>
> -					      ilog2(dev->ctrl.page_size));
> +					      ilog2(NVME_CTRL_PAGE_SIZE));

You could replace the ilog2() with NVME_CTRL_PAGE_SHIFT. Both compile to
the same result, though.



More information about the Linux-nvme mailing list