diff options
author | Oleg Nesterov <oleg@redhat.com> | 2010-08-10 21:03:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-11 11:59:20 -0400 |
commit | c52b0b91ba1f4b7ea90e20385c0a6df0ba54aed4 (patch) | |
tree | 6d92439150a3218da5807610991da4d70af56bf8 /kernel | |
parent | 5fdee8c4a5e1800489ce61963208f8cc55e42ea1 (diff) |
pids: alloc_pidmap: remove the unnecessary boundary checks
alloc_pidmap() calculates max_scan so that if the initial offset != 0 we
inspect the first map->page twice. This is correct, we want to find the
unused bits < offset in this bitmap block. Add the comment.
But it doesn't make any sense to stop the find_next_offset() loop when we
are looking into this map->page for the second time. We have already
already checked the bits >= offset during the first attempt, it is fine to
do this again, no matter if we succeed this time or not.
Remove this hard-to-understand code. It optimizes the very unlikely case
when we are going to fail, but slows down the more likely case.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Salman Qazi <sqazi@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Sukadev Bhattiprolu <sukadev@us.ibm.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/pid.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/kernel/pid.c b/kernel/pid.c index fbbd5f6b6f2f..d55c6fb8d087 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -169,7 +169,12 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) | |||
169 | pid = RESERVED_PIDS; | 169 | pid = RESERVED_PIDS; |
170 | offset = pid & BITS_PER_PAGE_MASK; | 170 | offset = pid & BITS_PER_PAGE_MASK; |
171 | map = &pid_ns->pidmap[pid/BITS_PER_PAGE]; | 171 | map = &pid_ns->pidmap[pid/BITS_PER_PAGE]; |
172 | max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset; | 172 | /* |
173 | * If last_pid points into the middle of the map->page we | ||
174 | * want to scan this bitmap block twice, the second time | ||
175 | * we start with offset == 0 (or RESERVED_PIDS). | ||
176 | */ | ||
177 | max_scan = DIV_ROUND_UP(pid_max, BITS_PER_PAGE) - !offset; | ||
173 | for (i = 0; i <= max_scan; ++i) { | 178 | for (i = 0; i <= max_scan; ++i) { |
174 | if (unlikely(!map->page)) { | 179 | if (unlikely(!map->page)) { |
175 | void *page = kzalloc(PAGE_SIZE, GFP_KERNEL); | 180 | void *page = kzalloc(PAGE_SIZE, GFP_KERNEL); |
@@ -196,15 +201,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) | |||
196 | } | 201 | } |
197 | offset = find_next_offset(map, offset); | 202 | offset = find_next_offset(map, offset); |
198 | pid = mk_pid(pid_ns, map, offset); | 203 | pid = mk_pid(pid_ns, map, offset); |
199 | /* | 204 | } while (offset < BITS_PER_PAGE && pid < pid_max); |
200 | * find_next_offset() found a bit, the pid from it | ||
201 | * is in-bounds, and if we fell back to the last | ||
202 | * bitmap block and the final block was the same | ||
203 | * as the starting point, pid is before last_pid. | ||
204 | */ | ||
205 | } while (offset < BITS_PER_PAGE && pid < pid_max && | ||
206 | (i != max_scan || pid < last || | ||
207 | !((last+1) & BITS_PER_PAGE_MASK))); | ||
208 | } | 205 | } |
209 | if (map < &pid_ns->pidmap[(pid_max-1)/BITS_PER_PAGE]) { | 206 | if (map < &pid_ns->pidmap[(pid_max-1)/BITS_PER_PAGE]) { |
210 | ++map; | 207 | ++map; |