On 11/29/18 12:17 AM, Manjunath Patil wrote: > 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 Since I suspect number of rings will likely be the same why not reuse the rings in the common case? > 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 > @@ -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, Why xenbus_dev_fatal()? -boris > + "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;