kernel/resource: refactor __request_region to allow external locking
Refactor the portion of __request_region() done whilst holding the resource_lock into a separate function to allow callers to hold the lock. Link: https://lkml.kernel.org/r/20210419070109.4780-2-apopple@nvidia.com Signed-off-by: Alistair Popple <apopple@nvidia.com> Reviewed-by: David Hildenbrand <david@redhat.com> Cc: Balbir Singh <bsingharora@gmail.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jerome Glisse <jglisse@redhat.com> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Muchun Song <smuchun@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
d486ccb252
commit
63cdafe0af
|
@ -1160,31 +1160,16 @@ struct address_space *iomem_get_mapping(void)
|
|||
return smp_load_acquire(&iomem_inode)->i_mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* __request_region - create a new busy resource region
|
||||
* @parent: parent resource descriptor
|
||||
* @start: resource start address
|
||||
* @n: resource region size
|
||||
* @name: reserving caller's ID string
|
||||
* @flags: IO resource flags
|
||||
*/
|
||||
struct resource * __request_region(struct resource *parent,
|
||||
static int __request_region_locked(struct resource *res, struct resource *parent,
|
||||
resource_size_t start, resource_size_t n,
|
||||
const char *name, int flags)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
struct resource *res = alloc_resource(GFP_KERNEL);
|
||||
struct resource *orig_parent = parent;
|
||||
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
res->name = name;
|
||||
res->start = start;
|
||||
res->end = start + n - 1;
|
||||
|
||||
write_lock(&resource_lock);
|
||||
|
||||
for (;;) {
|
||||
struct resource *conflict;
|
||||
|
||||
|
@ -1220,13 +1205,40 @@ struct resource * __request_region(struct resource *parent,
|
|||
continue;
|
||||
}
|
||||
/* Uhhuh, that didn't work out.. */
|
||||
free_resource(res);
|
||||
res = NULL;
|
||||
break;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __request_region - create a new busy resource region
|
||||
* @parent: parent resource descriptor
|
||||
* @start: resource start address
|
||||
* @n: resource region size
|
||||
* @name: reserving caller's ID string
|
||||
* @flags: IO resource flags
|
||||
*/
|
||||
struct resource *__request_region(struct resource *parent,
|
||||
resource_size_t start, resource_size_t n,
|
||||
const char *name, int flags)
|
||||
{
|
||||
struct resource *res = alloc_resource(GFP_KERNEL);
|
||||
int ret;
|
||||
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
write_lock(&resource_lock);
|
||||
ret = __request_region_locked(res, parent, start, n, name, flags);
|
||||
write_unlock(&resource_lock);
|
||||
|
||||
if (res && orig_parent == &iomem_resource)
|
||||
if (ret) {
|
||||
free_resource(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parent == &iomem_resource)
|
||||
revoke_iomem(res);
|
||||
|
||||
return res;
|
||||
|
|
Loading…
Reference in New Issue