Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 330201
b: refs/heads/master
c: 4965f56
h: refs/heads/master
i:
  330199: 43d042d
v: v3
  • Loading branch information
T Makphaibulchoke authored and Linus Torvalds committed Oct 5, 2012
1 parent 4c45b71 commit 6ffc8d9
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c99b6841d74a5c7d3698cc2a3ec44241fe64b769
refs/heads/master: 4965f5667f36a95b41cda6638875bc992bd7d18b
50 changes: 38 additions & 12 deletions trunk/kernel/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ static void __init __reserve_region_with_split(struct resource *root,
struct resource *parent = root;
struct resource *conflict;
struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC);
struct resource *next_res = NULL;

if (!res)
return;
Expand All @@ -772,21 +773,46 @@ static void __init __reserve_region_with_split(struct resource *root,
res->end = end;
res->flags = IORESOURCE_BUSY;

conflict = __request_resource(parent, res);
if (!conflict)
return;
while (1) {

/* failed, split and try again */
kfree(res);
conflict = __request_resource(parent, res);
if (!conflict) {
if (!next_res)
break;
res = next_res;
next_res = NULL;
continue;
}

/* conflict covered whole area */
if (conflict->start <= start && conflict->end >= end)
return;
/* conflict covered whole area */
if (conflict->start <= res->start &&
conflict->end >= res->end) {
kfree(res);
WARN_ON(next_res);
break;
}

/* failed, split and try again */
if (conflict->start > res->start) {
end = res->end;
res->end = conflict->start - 1;
if (conflict->end < end) {
next_res = kzalloc(sizeof(*next_res),
GFP_ATOMIC);
if (!next_res) {
kfree(res);
break;
}
next_res->name = name;
next_res->start = conflict->end + 1;
next_res->end = end;
next_res->flags = IORESOURCE_BUSY;
}
} else {
res->start = conflict->end + 1;
}
}

if (conflict->start > start)
__reserve_region_with_split(root, start, conflict->start-1, name);
if (conflict->end < end)
__reserve_region_with_split(root, conflict->end+1, end, name);
}

void __init reserve_region_with_split(struct resource *root,
Expand Down

0 comments on commit 6ffc8d9

Please sign in to comment.