On Mon, May 04, 2009 at 01:17:39AM -0700, sukadev@xxxxxxxxxxxxxxxxxx wrote: > From: Sukadev Bhattiprolu <sukadev@xxxxxxxxxxxxxxxxxx> > > > Signed-off-by: Sukadev Bhattiprolu <sukadev@xxxxxxxxxxxxxxxxxx> > --- > kernel/pid.c | 43 ++++++++++++++++++++++++++++--------------- > 1 files changed, 28 insertions(+), 15 deletions(-) > > diff --git a/kernel/pid.c b/kernel/pid.c > index b2e5f78..c0aaebe 100644 > --- a/kernel/pid.c > +++ b/kernel/pid.c > @@ -122,6 +122,31 @@ static void free_pidmap(struct upid *upid) > atomic_inc(&map->nr_free); > } > > +static int alloc_pidmap_page(struct pidmap *map) > +{ > + void *page; > + > + if (likely(map->page)) > + return 0; > + > + page = kzalloc(PAGE_SIZE, GFP_KERNEL); > + > + /* > + * Free the page if someone raced with us installing it: > + */ > + spin_lock_irq(&pidmap_lock); > + if (map->page) > + kfree(page); > + else > + map->page = page; > + spin_unlock_irq(&pidmap_lock); > + > + if (unlikely(!map->page)) > + return -1; > + > + return 0; > +} > + > static int alloc_pidmap(struct pid_namespace *pid_ns) > { > int i, offset, max_scan, pid, last = pid_ns->last_pid; > @@ -134,21 +159,9 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) > map = &pid_ns->pidmap[pid/BITS_PER_PAGE]; > max_scan = (pid_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); > - /* > - * Free the page if someone raced with us > - * installing it: > - */ > - spin_lock_irq(&pidmap_lock); > - if (map->page) > - kfree(page); > - else > - map->page = page; > - spin_unlock_irq(&pidmap_lock); > - if (unlikely(!map->page)) > - break; OK, I'm having trouble not with your patch but the original code. This test of map->page outside the spinlock looks like an incorrect fix to a race. If map->page can be NULL right after we release the lock then it can become NULL after this test just as easily. > - } > + if (alloc_pidmap_page(map)) > + break; > + > if (likely(atomic_read(&map->nr_free))) { > do { > if (!test_and_set_bit(offset, map->page)) { kaboom?? Perhaps I'm just not familiar enough with the code and I'm just seeing races where there are none... in which case perhaps a comment hinting at the answers would be good. Cheers, -Matt Helsley _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers