[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 12/14] xen-blkback: safely unmap grants in case they are still in use



El 23/01/15 a les 15.54, David Vrabel ha escrit:
> On 23/01/15 14:31, Roger Pau Monné wrote:
>> El 19/01/15 a les 16.51, David Vrabel ha escrit:
>>> From: Jenny Herbert <jennifer.herbert@xxxxxxxxxx>
>>>
>>> +static void xen_blkbk_unmap(struct xen_blkif *blkif,
>>> +                            struct grant_page *pages[],
>>> +                            int num)
>>> +{
>>> +   struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
>>> +   struct page *unmap_pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
>>> +   unsigned int invcount = 0;
>>> +   int ret;
>>> +
>>> +   while (num) {
>>> +           unsigned int batch = min(num, BLKIF_MAX_SEGMENTS_PER_REQUEST);
>>> +           
>>> +           invcount = xen_blkbk_unmap_prepare(blkif, pages, batch,
>>> +                                              unmap, unmap_pages);
>>
>> I would add:
>>
>> BUG_ON(invcount != batch);
> 
> I'm confused.  Surely invcount < batch is valid if one or more pages
> within this batch are persistently mapped?

Yes, my bad, see below.

> 
>>> +           if (invcount) {
>>> +                   ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, 
>>> invcount);
>>>                     BUG_ON(ret);
>>> -                   put_free_pages(blkif, unmap_pages, invcount);
>>> -                   invcount = 0;
>>> +                   xen_blkbk_unmap_done(blkif, unmap_pages, invcount);
>>>             }
>>> -   }
>>> -   if (invcount) {
>>> -           ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount);
>>> -           BUG_ON(ret);
>>> -           put_free_pages(blkif, unmap_pages, invcount);
>>> +           pages += batch;
>>> +           num -= batch;

This should be fixed to at least be (which is still not fully correct,
but it's better):

pages += invcount;
num -= invcount;

I hope an example will clarify this, suppose we have the following pages
array:

pages[0] = persistent grant
pages[1] = persistent grant
pages[2] = regular grant
pages[3] = persistent grant
pages[4] = regular grant

And batch is 1. In this case, the unmapped grant will be pages[2], but
then due to the code below pages will be updated to point to &pages[1],
which has already been scanned. If this was done correctly pages should
point to &pages[3]. As said, it's not really a bug, but the loop is
sub-optimal.

Roger.


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.