mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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;
|
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user