Skip to content

Commit 3f33647

Browse files
toshikaniIngo Molnar
authored and
Ingo Molnar
committed
resource: Add walk_iomem_res_desc()
Add a new interface, walk_iomem_res_desc(), which walks through the iomem table by identifying a target with @flags and @desc. This interface provides the same functionality as walk_iomem_res(), but does not use strcmp() to @name for better efficiency. walk_iomem_res() is deprecated and will be removed in a later patch. Requested-by: Borislav Petkov <[email protected]> Signed-off-by: Toshi Kani <[email protected]> [ Fixup comments. ] Signed-off-by: Borislav Petkov <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dan Williams <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Hanjun Guo <[email protected]> Cc: Jakub Sitnicki <[email protected]> Cc: Jiang Liu <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Luis R. Rodriguez <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rafael J. Wysocki <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Toshi Kani <[email protected]> Cc: [email protected] Cc: linux-mm <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 1c29f25 commit 3f33647

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

include/linux/ioport.h

+3
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ extern int
268268
walk_system_ram_res(u64 start, u64 end, void *arg,
269269
int (*func)(u64, u64, void *));
270270
extern int
271+
walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
272+
void *arg, int (*func)(u64, u64, void *));
273+
extern int
271274
walk_iomem_res(char *name, unsigned long flags, u64 start, u64 end, void *arg,
272275
int (*func)(u64, u64, void *));
273276

kernel/resource.c

+56-10
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,15 @@ int release_resource(struct resource *old)
333333
EXPORT_SYMBOL(release_resource);
334334

335335
/*
336-
* Finds the lowest iomem reosurce exists with-in [res->start.res->end)
337-
* the caller must specify res->start, res->end, res->flags and "name".
338-
* If found, returns 0, res is overwritten, if not found, returns -1.
339-
* This walks through whole tree and not just first level children
340-
* until and unless first_level_children_only is true.
336+
* Finds the lowest iomem resource existing within [res->start.res->end).
337+
* The caller must specify res->start, res->end, res->flags, and optionally
338+
* desc and "name". If found, returns 0, res is overwritten, if not found,
339+
* returns -1.
340+
* This function walks the whole tree and not just first level children until
341+
* and unless first_level_children_only is true.
341342
*/
342-
static int find_next_iomem_res(struct resource *res, char *name,
343-
bool first_level_children_only)
343+
static int find_next_iomem_res(struct resource *res, unsigned long desc,
344+
char *name, bool first_level_children_only)
344345
{
345346
resource_size_t start, end;
346347
struct resource *p;
@@ -360,6 +361,8 @@ static int find_next_iomem_res(struct resource *res, char *name,
360361
for (p = iomem_resource.child; p; p = next_resource(p, sibling_only)) {
361362
if ((p->flags & res->flags) != res->flags)
362363
continue;
364+
if ((desc != IORES_DESC_NONE) && (desc != p->desc))
365+
continue;
363366
if (name && strcmp(p->name, name))
364367
continue;
365368
if (p->start > end) {
@@ -385,12 +388,55 @@ static int find_next_iomem_res(struct resource *res, char *name,
385388
* Walks through iomem resources and calls func() with matching resource
386389
* ranges. This walks through whole tree and not just first level children.
387390
* All the memory ranges which overlap start,end and also match flags and
391+
* desc are valid candidates.
392+
*
393+
* @desc: I/O resource descriptor. Use IORES_DESC_NONE to skip @desc check.
394+
* @flags: I/O resource flags
395+
* @start: start addr
396+
* @end: end addr
397+
*
398+
* NOTE: For a new descriptor search, define a new IORES_DESC in
399+
* <linux/ioport.h> and set it in 'desc' of a target resource entry.
400+
*/
401+
int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start,
402+
u64 end, void *arg, int (*func)(u64, u64, void *))
403+
{
404+
struct resource res;
405+
u64 orig_end;
406+
int ret = -1;
407+
408+
res.start = start;
409+
res.end = end;
410+
res.flags = flags;
411+
orig_end = res.end;
412+
413+
while ((res.start < res.end) &&
414+
(!find_next_iomem_res(&res, desc, NULL, false))) {
415+
416+
ret = (*func)(res.start, res.end, arg);
417+
if (ret)
418+
break;
419+
420+
res.start = res.end + 1;
421+
res.end = orig_end;
422+
}
423+
424+
return ret;
425+
}
426+
427+
/*
428+
* Walks through iomem resources and calls @func with matching resource
429+
* ranges. This walks the whole tree and not just first level children.
430+
* All the memory ranges which overlap start,end and also match flags and
388431
* name are valid candidates.
389432
*
390433
* @name: name of resource
391434
* @flags: resource flags
392435
* @start: start addr
393436
* @end: end addr
437+
*
438+
* NOTE: This function is deprecated and should not be used in new code.
439+
* Use walk_iomem_res_desc(), instead.
394440
*/
395441
int walk_iomem_res(char *name, unsigned long flags, u64 start, u64 end,
396442
void *arg, int (*func)(u64, u64, void *))
@@ -404,7 +450,7 @@ int walk_iomem_res(char *name, unsigned long flags, u64 start, u64 end,
404450
res.flags = flags;
405451
orig_end = res.end;
406452
while ((res.start < res.end) &&
407-
(!find_next_iomem_res(&res, name, false))) {
453+
(!find_next_iomem_res(&res, IORES_DESC_NONE, name, false))) {
408454
ret = (*func)(res.start, res.end, arg);
409455
if (ret)
410456
break;
@@ -433,7 +479,7 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
433479
res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
434480
orig_end = res.end;
435481
while ((res.start < res.end) &&
436-
(!find_next_iomem_res(&res, NULL, true))) {
482+
(!find_next_iomem_res(&res, IORES_DESC_NONE, NULL, true))) {
437483
ret = (*func)(res.start, res.end, arg);
438484
if (ret)
439485
break;
@@ -463,7 +509,7 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
463509
res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
464510
orig_end = res.end;
465511
while ((res.start < res.end) &&
466-
(find_next_iomem_res(&res, NULL, true) >= 0)) {
512+
(find_next_iomem_res(&res, IORES_DESC_NONE, NULL, true) >= 0)) {
467513
pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
468514
end_pfn = (res.end + 1) >> PAGE_SHIFT;
469515
if (end_pfn > pfn)

0 commit comments

Comments
 (0)