Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 208539
b: refs/heads/master
c: 5fdee8c
h: refs/heads/master
i:
  208537: c789673
  208535: 572afed
v: v3
  • Loading branch information
Salman authored and Linus Torvalds committed Aug 11, 2010
1 parent 37e26ea commit aa20924
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 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: 9c867fbe06458a8957024236b574733fae0cefed
refs/heads/master: 5fdee8c4a5e1800489ce61963208f8cc55e42ea1
39 changes: 38 additions & 1 deletion trunk/kernel/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,43 @@ static void free_pidmap(struct upid *upid)
atomic_inc(&map->nr_free);
}

/*
* If we started walking pids at 'base', is 'a' seen before 'b'?
*/
static int pid_before(int base, int a, int b)
{
/*
* This is the same as saying
*
* (a - base + MAXUINT) % MAXUINT < (b - base + MAXUINT) % MAXUINT
* and that mapping orders 'a' and 'b' with respect to 'base'.
*/
return (unsigned)(a - base) < (unsigned)(b - base);
}

/*
* We might be racing with someone else trying to set pid_ns->last_pid.
* We want the winner to have the "later" value, because if the
* "earlier" value prevails, then a pid may get reused immediately.
*
* Since pids rollover, it is not sufficient to just pick the bigger
* value. We have to consider where we started counting from.
*
* 'base' is the value of pid_ns->last_pid that we observed when
* we started looking for a pid.
*
* 'pid' is the pid that we eventually found.
*/
static void set_last_pid(struct pid_namespace *pid_ns, int base, int pid)
{
int prev;
int last_write = base;
do {
prev = last_write;
last_write = cmpxchg(&pid_ns->last_pid, prev, pid);
} while ((prev != last_write) && (pid_before(base, last_write, pid)));
}

static int alloc_pidmap(struct pid_namespace *pid_ns)
{
int i, offset, max_scan, pid, last = pid_ns->last_pid;
Expand Down Expand Up @@ -154,7 +191,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
do {
if (!test_and_set_bit(offset, map->page)) {
atomic_dec(&map->nr_free);
pid_ns->last_pid = pid;
set_last_pid(pid_ns, last, pid);
return pid;
}
offset = find_next_offset(map, offset);
Expand Down

0 comments on commit aa20924

Please sign in to comment.