Commit 63cdafe0 authored by Alistair Popple's avatar Alistair Popple Committed by Linus Torvalds

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.comSigned-off-by: default avatarAlistair Popple <apopple@nvidia.com>
Reviewed-by: default avatarDavid 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d486ccb2
...@@ -1160,31 +1160,16 @@ struct address_space *iomem_get_mapping(void) ...@@ -1160,31 +1160,16 @@ struct address_space *iomem_get_mapping(void)
return smp_load_acquire(&iomem_inode)->i_mapping; return smp_load_acquire(&iomem_inode)->i_mapping;
} }
/** static int __request_region_locked(struct resource *res, struct resource *parent,
* __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, resource_size_t start, resource_size_t n,
const char *name, int flags) const char *name, int flags)
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
struct resource *res = alloc_resource(GFP_KERNEL);
struct resource *orig_parent = parent;
if (!res)
return NULL;
res->name = name; res->name = name;
res->start = start; res->start = start;
res->end = start + n - 1; res->end = start + n - 1;
write_lock(&resource_lock);
for (;;) { for (;;) {
struct resource *conflict; struct resource *conflict;
...@@ -1220,13 +1205,40 @@ struct resource * __request_region(struct resource *parent, ...@@ -1220,13 +1205,40 @@ struct resource * __request_region(struct resource *parent,
continue; continue;
} }
/* Uhhuh, that didn't work out.. */ /* Uhhuh, that didn't work out.. */
free_resource(res); return -EBUSY;
res = NULL;
break;
} }
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); write_unlock(&resource_lock);
if (res && orig_parent == &iomem_resource) if (ret) {
free_resource(res);
return NULL;
}
if (parent == &iomem_resource)
revoke_iomem(res); revoke_iomem(res);
return res; return res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment