[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <23742bb8-831f-29ff-1463-75427eec57c7@oracle.com>
Date: Mon, 6 Apr 2020 11:43:51 +0100
From: Joao Martins <joao.m.martins@...cle.com>
To: Dan Williams <dan.j.williams@...el.com>
Cc: linux-mm@...ck.org, dave.hansen@...ux.intel.com, hch@....de,
linux-nvdimm@...ts.01.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 11/12] device-dax: Add dis-contiguous resource support
On 3/23/20 11:55 PM, Dan Williams wrote:
[...]
> static ssize_t dev_dax_resize(struct dax_region *dax_region,
> struct dev_dax *dev_dax, resource_size_t size)
> {
> resource_size_t avail = dax_region_avail_size(dax_region), to_alloc;
> - resource_size_t dev_size = range_len(&dev_dax->range);
> + resource_size_t dev_size = dev_dax_size(dev_dax);
> struct resource *region_res = &dax_region->res;
> struct device *dev = &dev_dax->dev;
> - const char *name = dev_name(dev);
> struct resource *res, *first;
> + resource_size_t alloc = 0;
> + int rc;
>
> if (dev->driver)
> return -EBUSY;
> @@ -684,38 +766,47 @@ static ssize_t dev_dax_resize(struct dax_region *dax_region,
> * allocating a new resource.
> */
> first = region_res->child;
> - if (!first)
> - return __alloc_dev_dax_range(dev_dax, dax_region->res.start,
> - to_alloc);
> - for (res = first; to_alloc && res; res = res->sibling) {
> +retry:
> + rc = -ENOSPC;
> + for (res = first; res; res = res->sibling) {
> struct resource *next = res->sibling;
> - resource_size_t free;
>
> /* space at the beginning of the region */
> - free = 0;
> - if (res == first && res->start > dax_region->res.start)
> - free = res->start - dax_region->res.start;
> - if (free >= to_alloc && dev_size == 0)
> - return __alloc_dev_dax_range(dev_dax,
> - dax_region->res.start, to_alloc);
> -
> - free = 0;
> + if (res == first && res->start > dax_region->res.start) {
> + alloc = min(res->start - dax_region->res.start,
> + to_alloc);
> + rc = __alloc_dev_dax_range(dev_dax,
> + dax_region->res.start, alloc);
You might be missing:
first = region_res->child;
(...) right after returning from __alloc_dev_dax_range(). Alternatively, perhaps
even moving the 'retry' label to right before the @first initialization.
In the case that you pick space from the beginning, the child resource of the
dax region will point to first occupied region, and that changes after you pick
this space. So, IIUC, you want to adjust where you start searching free space
otherwise you end up wrongly picking that same space twice.
If it helps, the bug can be reproduced in this unit test below, see
daxctl_test3() test:
https://lore.kernel.org/linux-nvdimm/20200403205900.18035-11-joao.m.martins@oracle.com/
> + break;
> + }
> +
[...]
Powered by blists - more mailing lists