Re: [RFC][v8][PATCH 0/10] Implement clone3() system call

From: Eric W. Biederman
Date: Wed Oct 21 2009 - 05:17:02 EST


Sukadev Bhattiprolu <sukadev@xxxxxxxxxxxxxxxxxx> writes:

> Eric W. Biederman [ebiederm@xxxxxxxxxxxx] wrote:
> | > I will post a version of the patch outside this patchset with min
> | > and max parameters and we can see if it can be optimized/beautified.
> |
> | Thanks,
> | Eric
>
> Here is the patch. alloc_pid() calls alloc_pidmap() as follows:
>
> - nr = alloc_pidmap(tmp);
> + min = max = 0;
> + if (target_pids) {
> + min = target_pids[i];
> + max = min + 1;
> + }
> + nr = alloc_pidmap(tmp, min, max);
>
> It does look like this patch executes a bit more code even in the common
> case but let me know if you think this is better.
>
> ---

Not what I was thinking. The following untested patch is what I was
thinking. It just exposes last, min, and max to the callers which pass
in different appropriate values.

Eric

diff --git a/kernel/pid.c b/kernel/pid.c
index d3f722d..d9b6f82 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -122,17 +122,17 @@ static void free_pidmap(struct upid *upid)
atomic_inc(&map->nr_free);
}

-static int alloc_pidmap(struct pid_namespace *pid_ns)
+static int do_alloc_pidmap(struct pid_namespace *pid_ns, int last, int min, int max)
{
- int i, offset, max_scan, pid, last = pid_ns->last_pid;
+ int i, offset, max_scan, pid;
struct pidmap *map;

pid = last + 1;
- if (pid >= pid_max)
- pid = RESERVED_PIDS;
+ if (pid >= max)
+ pid = min;
offset = pid & BITS_PER_PAGE_MASK;
map = &pid_ns->pidmap[pid/BITS_PER_PAGE];
- max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
+ max_scan = (max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
for (i = 0; i <= max_scan; ++i) {
if (unlikely(!map->page)) {
void *page = kzalloc(PAGE_SIZE, GFP_KERNEL);
@@ -153,7 +153,6 @@ 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;
return pid;
}
offset = find_next_offset(map, offset);
@@ -164,16 +163,16 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
* bitmap block and the final block was the same
* as the starting point, pid is before last_pid.
*/
- } while (offset < BITS_PER_PAGE && pid < pid_max &&
+ } while (offset < BITS_PER_PAGE && pid < max &&
(i != max_scan || pid < last ||
!((last+1) & BITS_PER_PAGE_MASK)));
}
- if (map < &pid_ns->pidmap[(pid_max-1)/BITS_PER_PAGE]) {
+ if (map < &pid_ns->pidmap[(max-1)/BITS_PER_PAGE]) {
++map;
offset = 0;
} else {
map = &pid_ns->pidmap[0];
- offset = RESERVED_PIDS;
+ offset = min;
if (unlikely(last == offset))
break;
}
@@ -182,6 +181,25 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
return -1;
}

+static int alloc_pidmap(struct pid_namespace *pid_ns)
+{
+ int nr;
+
+ nr = do_alloc_pidmap(pid_ns, pid_ns->last, RESERVED_PIDS, pid_max);
+ if (nr >= 0)
+ pid_ns->last_pid = nr;
+ return nr;
+}
+
+static int set_pidmap(struct pid_namespace *pid_ns, int target)
+{
+ if (target >= pid_max)
+ return -1;
+ if (target < RESERVED_PIDS)
+ return -1;
+ return do_alloc_pidmap(pid_ns, target - 1, target, target + 1);
+}
+
int next_pidmap(struct pid_namespace *pid_ns, int last)
{
int offset;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/