diff mbox series

xen/blkfront: limit allocated memory size to actual use case

Message ID 20200117143955.18892-1-jgross@suse.com (mailing list archive)
State Accepted
Commit 0265d6e8ddb8901c2c03d09f9444f382a60ba6b1
Headers show
Series xen/blkfront: limit allocated memory size to actual use case | expand

Commit Message

Jürgen Groß Jan. 17, 2020, 2:39 p.m. UTC
Today the Xen blkfront driver allocates memory for one struct
blkfront_ring_info for each communication ring. This structure is
statically sized for the maximum supported configuration resulting
in a size of more than 90 kB.

As the main size contributor is one array inside the struct, the
memory allocation can easily be limited by moving this array to be
the last structure element and to allocate only the memory for the
actually needed array size.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 drivers/block/xen-blkfront.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

Comments

Roger Pau Monné Jan. 17, 2020, 3:13 p.m. UTC | #1
On Fri, Jan 17, 2020 at 03:39:55PM +0100, Juergen Gross wrote:
> Today the Xen blkfront driver allocates memory for one struct
> blkfront_ring_info for each communication ring. This structure is
> statically sized for the maximum supported configuration resulting
> in a size of more than 90 kB.
> 
> As the main size contributor is one array inside the struct, the
> memory allocation can easily be limited by moving this array to be
> the last structure element and to allocate only the memory for the
> actually needed array size.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>

Acked-by: Roger Pau Monné <roger.pau@citrix.com>

Thanks! It would be nice to backport this, but I'm not sure it would
qualify as a bug fix.

Roger.
diff mbox series

Patch

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index c02be06c5299..61491167da19 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -151,9 +151,6 @@  MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the
 #define BLK_RING_SIZE(info)	\
 	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
 
-#define BLK_MAX_RING_SIZE	\
-	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * XENBUS_MAX_RING_GRANTS)
-
 /*
  * ring-ref%u i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
  * characters are enough. Define to 20 to keep consistent with backend.
@@ -177,12 +174,12 @@  struct blkfront_ring_info {
 	unsigned int evtchn, irq;
 	struct work_struct work;
 	struct gnttab_free_callback callback;
-	struct blk_shadow shadow[BLK_MAX_RING_SIZE];
 	struct list_head indirect_pages;
 	struct list_head grants;
 	unsigned int persistent_gnts_c;
 	unsigned long shadow_free;
 	struct blkfront_info *dev_info;
+	struct blk_shadow shadow[];
 };
 
 /*
@@ -1915,7 +1912,8 @@  static int negotiate_mq(struct blkfront_info *info)
 		info->nr_rings = 1;
 
 	info->rinfo = kvcalloc(info->nr_rings,
-			       sizeof(struct blkfront_ring_info),
+			       struct_size(info->rinfo, shadow,
+					   BLK_RING_SIZE(info)),
 			       GFP_KERNEL);
 	if (!info->rinfo) {
 		xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");