fix pid_max handling. Wrap around correctly. Signed-off-by: William Lee Irwin III Signed-off-by: Ingo Molnar --- 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: