diff mbox series

[v2,1/1] PCI: hv: Fix ring buffer size calculation

Message ID 20240215074823.51014-1-mhklinux@outlook.com
State New
Headers show
Series [v2,1/1] PCI: hv: Fix ring buffer size calculation | expand

Commit Message

Michael Kelley Feb. 15, 2024, 7:48 a.m. UTC
From: Michael Kelley <mhklinux@outlook.com>

For a physical PCI device that is passed through to a Hyper-V guest VM,
current code specifies the VMBus ring buffer size as 4 pages.  But this
is an inappropriate dependency, since the amount of ring buffer space
needed is unrelated to PAGE_SIZE. For example, on x86 the ring buffer
size ends up as 16 Kbytes, while on ARM64 with 64 Kbyte pages, the ring
size bloats to 256 Kbytes. The ring buffer for PCI pass-thru devices
is used for only a few messages during device setup and removal, so any
space above a few Kbytes is wasted.

Fix this by declaring the ring buffer size to be a fixed 16 Kbytes.
Furthermore, use the VMBUS_RING_SIZE() macro so that the ring buffer
header is properly accounted for, and so the size is rounded up to a
page boundary, using the page size for which the kernel is built. While
w/64 Kbyte pages this results in a 64 Kbyte ring buffer header plus a
64 Kbyte ring buffer, that's the smallest possible with that page size.
It's still 128 Kbytes better than the current code.

Cc: <stable@vger.kernel.org> # 5.15.x
Signed-off-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
Changes in v2:
* Use SZ_16K instead of 16 * 1024
---
 drivers/pci/controller/pci-hyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Ilpo Järvinen Feb. 16, 2024, 2:46 p.m. UTC | #1
On Wed, 14 Feb 2024, mhkelley58@gmail.com wrote:

> From: Michael Kelley <mhklinux@outlook.com>
> 
> For a physical PCI device that is passed through to a Hyper-V guest VM,
> current code specifies the VMBus ring buffer size as 4 pages.  But this
> is an inappropriate dependency, since the amount of ring buffer space
> needed is unrelated to PAGE_SIZE. For example, on x86 the ring buffer
> size ends up as 16 Kbytes, while on ARM64 with 64 Kbyte pages, the ring
> size bloats to 256 Kbytes. The ring buffer for PCI pass-thru devices
> is used for only a few messages during device setup and removal, so any
> space above a few Kbytes is wasted.
> 
> Fix this by declaring the ring buffer size to be a fixed 16 Kbytes.
> Furthermore, use the VMBUS_RING_SIZE() macro so that the ring buffer
> header is properly accounted for, and so the size is rounded up to a
> page boundary, using the page size for which the kernel is built. While
> w/64 Kbyte pages this results in a 64 Kbyte ring buffer header plus a
> 64 Kbyte ring buffer, that's the smallest possible with that page size.
> It's still 128 Kbytes better than the current code.
> 
> Cc: <stable@vger.kernel.org> # 5.15.x
> Signed-off-by: Michael Kelley <mhklinux@outlook.com>
> Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> ---
> Changes in v2:
> * Use SZ_16K instead of 16 * 1024
> ---
>  drivers/pci/controller/pci-hyperv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index 1eaffff40b8d..baadc1e5090e 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -465,7 +465,7 @@ struct pci_eject_response {
>  	u32 status;
>  } __packed;
>  
> -static int pci_ring_size = (4 * PAGE_SIZE);
> +static int pci_ring_size = VMBUS_RING_SIZE(SZ_16K);
>  
>  /*
>   * Driver specific state.
> 

Hi,

You forgot to add #include <linux/sizes.h> for it.

With that fixed:

Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Michael Kelley Feb. 16, 2024, 8:28 p.m. UTC | #2
From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Sent: Friday, February 16, 2024 6:46 AM
> 
> On Wed, 14 Feb 2024, mhkelley58@gmail.com wrote:
> >
> > For a physical PCI device that is passed through to a Hyper-V guest VM,
> > current code specifies the VMBus ring buffer size as 4 pages.  But this
> > is an inappropriate dependency, since the amount of ring buffer space
> > needed is unrelated to PAGE_SIZE. For example, on x86 the ring buffer
> > size ends up as 16 Kbytes, while on ARM64 with 64 Kbyte pages, the ring
> > size bloats to 256 Kbytes. The ring buffer for PCI pass-thru devices
> > is used for only a few messages during device setup and removal, so any
> > space above a few Kbytes is wasted.
> >
> > Fix this by declaring the ring buffer size to be a fixed 16 Kbytes.
> > Furthermore, use the VMBUS_RING_SIZE() macro so that the ring buffer
> > header is properly accounted for, and so the size is rounded up to a
> > page boundary, using the page size for which the kernel is built. While
> > w/64 Kbyte pages this results in a 64 Kbyte ring buffer header plus a
> > 64 Kbyte ring buffer, that's the smallest possible with that page size.
> > It's still 128 Kbytes better than the current code.
> >
> > Cc: <stable@vger.kernel.org> # 5.15.x
> > Signed-off-by: Michael Kelley <mhklinux@outlook.com>
> > Reviewed-by: Kuppuswamy Sathyanarayanan
> <sathyanarayanan.kuppuswamy@linux.intel.com>
> > ---
> > Changes in v2:
> > * Use SZ_16K instead of 16 * 1024
> > ---
> >  drivers/pci/controller/pci-hyperv.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-
> hyperv.c
> > index 1eaffff40b8d..baadc1e5090e 100644
> > --- a/drivers/pci/controller/pci-hyperv.c
> > +++ b/drivers/pci/controller/pci-hyperv.c
> > @@ -465,7 +465,7 @@ struct pci_eject_response {
> >  	u32 status;
> >  } __packed;
> >
> > -static int pci_ring_size = (4 * PAGE_SIZE);
> > +static int pci_ring_size = VMBUS_RING_SIZE(SZ_16K);
> >
> >  /*
> >   * Driver specific state.
> >
> 
> Hi,
> 
> You forgot to add #include <linux/sizes.h> for it.
> 
> With that fixed:
> 
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> 

Fixed in v3.  I mis-interpreted your previous comment about
adding the #include "if needed".  It's not needed to compile
correctly, as sizes.h is indirectly included through some other
#include.  But it's better to directly #include what's needed
lest some unrelated change cause a failure.

Michael
Ilpo Järvinen Feb. 19, 2024, 10:47 a.m. UTC | #3
On Fri, 16 Feb 2024, Michael Kelley wrote:

> From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Sent: Friday, February 16, 2024 6:46 AM
> > 
> > On Wed, 14 Feb 2024, mhkelley58@gmail.com wrote:
> > >
> > > For a physical PCI device that is passed through to a Hyper-V guest VM,
> > > current code specifies the VMBus ring buffer size as 4 pages.  But this
> > > is an inappropriate dependency, since the amount of ring buffer space
> > > needed is unrelated to PAGE_SIZE. For example, on x86 the ring buffer
> > > size ends up as 16 Kbytes, while on ARM64 with 64 Kbyte pages, the ring
> > > size bloats to 256 Kbytes. The ring buffer for PCI pass-thru devices
> > > is used for only a few messages during device setup and removal, so any
> > > space above a few Kbytes is wasted.
> > >
> > > Fix this by declaring the ring buffer size to be a fixed 16 Kbytes.
> > > Furthermore, use the VMBUS_RING_SIZE() macro so that the ring buffer
> > > header is properly accounted for, and so the size is rounded up to a
> > > page boundary, using the page size for which the kernel is built. While
> > > w/64 Kbyte pages this results in a 64 Kbyte ring buffer header plus a
> > > 64 Kbyte ring buffer, that's the smallest possible with that page size.
> > > It's still 128 Kbytes better than the current code.
> > >
> > > Cc: <stable@vger.kernel.org> # 5.15.x
> > > Signed-off-by: Michael Kelley <mhklinux@outlook.com>
> > > Reviewed-by: Kuppuswamy Sathyanarayanan
> > <sathyanarayanan.kuppuswamy@linux.intel.com>
> > > ---
> > > Changes in v2:
> > > * Use SZ_16K instead of 16 * 1024
> > > ---
> > >  drivers/pci/controller/pci-hyperv.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-
> > hyperv.c
> > > index 1eaffff40b8d..baadc1e5090e 100644
> > > --- a/drivers/pci/controller/pci-hyperv.c
> > > +++ b/drivers/pci/controller/pci-hyperv.c
> > > @@ -465,7 +465,7 @@ struct pci_eject_response {
> > >  	u32 status;
> > >  } __packed;
> > >
> > > -static int pci_ring_size = (4 * PAGE_SIZE);
> > > +static int pci_ring_size = VMBUS_RING_SIZE(SZ_16K);
> > >
> > >  /*
> > >   * Driver specific state.
> > >
> > 
> > Hi,
> > 
> > You forgot to add #include <linux/sizes.h> for it.
> > 
> > With that fixed:
> > 
> > Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > 
> 
> Fixed in v3.  I mis-interpreted your previous comment about
> adding the #include "if needed".  It's not needed to compile
> correctly, as sizes.h is indirectly included through some other
> #include.  But it's better to directly #include what's needed
> lest some unrelated change cause a failure.

Yes, we try include the headers we use in the .c file. I used "if needed" 
because I didn't check if it was already among the #includes in the file.

Our tools are lacking to enforce/check a file has correct set of #includes 
so it's currently based mostly on reviewers noticing something is wrong 
with #includes, hopefully some time in the future, the tools also catch 
up.
diff mbox series

Patch

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 1eaffff40b8d..baadc1e5090e 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -465,7 +465,7 @@  struct pci_eject_response {
 	u32 status;
 } __packed;
 
-static int pci_ring_size = (4 * PAGE_SIZE);
+static int pci_ring_size = VMBUS_RING_SIZE(SZ_16K);
 
 /*
  * Driver specific state.