linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] xen-blkfront: use old rinfo after enomem during migration
@ 2018-11-29  5:17 Manjunath Patil
  2018-11-30 20:42 ` [Xen-devel] " Boris Ostrovsky
  0 siblings, 1 reply; 11+ messages in thread
From: Manjunath Patil @ 2018-11-29  5:17 UTC (permalink / raw)
  To: boris.ostrovsky, jgross, konrad.wilk, roger.pau, axboe
  Cc: xen-devel, linux-block, manjuanth.b.patil

Hi,
Feel free to suggest/comment on this.

I am trying to do the following at dst during the migration now.
1. Dont clear the old rinfo in blkif_free(). Instead just clean it.
2. Store the old rinfo and nr_rings into temp variables in negotiate_mq()
3. let nr_rings get re-calculated based on backend data
4. try allocating new memory based on new nr_rings
5. 
  a. If memory allocation is a success
     - free the old rinfo and proceed to use the new rinfo
  b. If memory allocation is a failure
     - use the old the rinfo
     - adjust the nr_rings to the lowest of new nr_rings and old nr_rings

-Thanks,
Manjunath
--
During migration, the dst side device resume can fail to allocate rinfo
struct. Each rinfo is about 80K in size and allocating 4[typical] such
rings would need an order 7 allocation[512KB chuck] there by incresing
the chance of memory allocation failure. Device resume failure during
migration will lead the processes accessing the device into hung state.

This patch aims to reuse old rinfo in case of memory allocation failure.

Signed-off-by: Manjunath Patil <manjunath.b.patil@oracle.com>
---
 drivers/block/xen-blkfront.c |   46 +++++++++++++++++++++++++++++++++++------
 1 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 0ed4b20..041ba67 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1353,9 +1353,17 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 	for (i = 0; i < info->nr_rings; i++)
 		blkif_free_ring(&info->rinfo[i]);
 
-	kfree(info->rinfo);
-	info->rinfo = NULL;
-	info->nr_rings = 0;
+	if (unlikely(info->connected == BLKIF_STATE_SUSPENDED)) {
+		/* We are migrating. You may reuse it. Just clean. */
+		for (i = 0; i < info->nr_rings; i++) {
+			memset(&info->rinfo[i], 0,
+				sizeof(struct blkfront_ring_info));
+		}
+	} else {
+		kfree(info->rinfo);
+		info->rinfo = NULL;
+		info->nr_rings = 0;
+	}
 }
 
 struct copy_from_grant {
@@ -1903,6 +1911,16 @@ static int negotiate_mq(struct blkfront_info *info)
 {
 	unsigned int backend_max_queues;
 	unsigned int i;
+	struct blkfront_ring_info *rinfo_old = NULL;
+	unsigned int nr_rings_old = 0;
+
+	/* Migrating. We did not free old rinfo. Reuse it if possible */
+	if (unlikely(info->connected == BLKIF_STATE_SUSPENDED)) {
+		nr_rings_old = info->nr_rings;
+		rinfo_old = info->rinfo;
+		info->rinfo = NULL;
+		info->nr_rings = 0;
+	}
 
 	BUG_ON(info->nr_rings);
 
@@ -1918,10 +1936,24 @@ static int negotiate_mq(struct blkfront_info *info)
 			      sizeof(struct blkfront_ring_info),
 			      GFP_KERNEL);
 	if (!info->rinfo) {
-		xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
-		info->nr_rings = 0;
-		return -ENOMEM;
-	}
+		if (unlikely(nr_rings_old)) {
+			/* We might waste some memory if
+			 * info->nr_rings < nr_rings_old
+			 */
+			info->rinfo = rinfo_old;
+			if (info->nr_rings > nr_rings_old)
+				info->nr_rings = nr_rings_old;
+			xenbus_dev_fatal(info->xbdev, -ENOMEM,
+			"reusing old ring_info structure(new ring size=%d)",
+				info->nr_rings);
+		} else {
+			xenbus_dev_fatal(info->xbdev, -ENOMEM,
+				"allocating ring_info structure");
+			info->nr_rings = 0;
+			return -ENOMEM;
+		}
+	} else if (unlikely(nr_rings_old))
+		kfree(rinfo_old);
 
 	for (i = 0; i < info->nr_rings; i++) {
 		struct blkfront_ring_info *rinfo;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-12-04  5:57 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-29  5:17 [PATCH] xen-blkfront: use old rinfo after enomem during migration Manjunath Patil
2018-11-30 20:42 ` [Xen-devel] " Boris Ostrovsky
2018-11-30 21:49   ` Manjunath Patil
2018-11-30 22:33     ` Boris Ostrovsky
2018-12-02 20:31       ` Manjunath Patil
2018-12-03 16:07         ` Boris Ostrovsky
2018-12-04  1:14           ` Dongli Zhang
2018-12-04  2:16             ` Boris Ostrovsky
2018-12-04  2:49               ` Manjunath Patil
2018-12-04  3:17                 ` Dongli Zhang
2018-12-04  5:57             ` Juergen Gross

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).