Messages in this thread Patch in this message | | | Date | Sun, 12 Sep 2004 12:13:50 +0200 | From | Ingo Molnar <> | Subject | Re: /proc/sys/kernel/pid_max issues |
| |
* William Lee Irwin III <wli@holomorphy.com> wrote:
> If pid_max == BITS_PER_PAGE*n, none of > &pidmap_array[pid_max/BITS_PER_PAGE] is usable, so if we must complete > a full revolution around pidmap_array[] to discover a free pid > slightly less than last_pid we will miss it. Hence:
yeah. Patch needs testing ...
> if (++map == map_limit) > map = pidmap_array; > + if (map > &pidmap_array[(pid_max-1)/BITS_PER_PAGE]) > + map = pidmap_array;
in fact we can now merge the max_limit and pid_max checks - see the attached updated patch.
Ingo
fix pid_max handling. Wrap around correctly.
Signed-off-by: William Lee Irwin III <wli@holomorphy.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
--- linux/kernel/pid.c.orig +++ linux/kernel/pid.c @@ -53,8 +53,6 @@ typedef struct pidmap { static pidmap_t pidmap_array[PIDMAP_ENTRIES] = { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } }; -static pidmap_t *map_limit = pidmap_array + PIDMAP_ENTRIES; - static spinlock_t pidmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; fastcall void free_pidmap(int pid) @@ -73,7 +71,9 @@ fastcall void free_pidmap(int pid) static inline pidmap_t *next_free_map(pidmap_t *map, int *max_steps) { while (--*max_steps) { - if (++map == map_limit) + pidmap_t *map_limit = pidmap_array + (pid_max-1)/BITS_PER_PAGE; + + if (++map > map_limit) map = pidmap_array; if (unlikely(!map->page)) { unsigned long page = get_zeroed_page(GFP_KERNEL); @@ -133,13 +133,12 @@ next_map: */ scan_more: offset = find_next_zero_bit(map->page, BITS_PER_PAGE, offset); - if (offset >= BITS_PER_PAGE) + pid = (map - pidmap_array) * BITS_PER_PAGE + offset; + if (offset >= BITS_PER_PAGE || pid >= pid_max) goto next_map; if (test_and_set_bit(offset, map->page)) goto scan_more; - /* we got the PID: */ - pid = (map - pidmap_array) * BITS_PER_PAGE + offset; goto return_pid; failure:
| |