Re: [PATCH 13/26] ppc: Convert mmu context allocation to new IDA API

From: Nicholas Piggin
Date: Fri Jun 22 2018 - 00:53:30 EST


On Thu, 21 Jun 2018 21:38:15 -0700
Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:

> On Fri, Jun 22, 2018 at 12:15:11PM +1000, Nicholas Piggin wrote:
> > On Thu, 21 Jun 2018 14:28:22 -0700
> > Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
> > > static int alloc_context_id(int min_id, int max_id)
> ...
> > > - spin_lock(&mmu_context_lock);
> > > - err = ida_get_new_above(&mmu_context_ida, min_id, &index);
> > > - spin_unlock(&mmu_context_lock);
> ...
> > > @@ -182,13 +148,11 @@ static void destroy_contexts(mm_context_t *ctx)
> > > {
> > > int index, context_id;
> > >
> > > - spin_lock(&mmu_context_lock);
> > > for (index = 0; index < ARRAY_SIZE(ctx->extended_id); index++) {
> > > context_id = ctx->extended_id[index];
> > > if (context_id)
> > > - ida_remove(&mmu_context_ida, context_id);
> > > + ida_free(&mmu_context_ida, context_id);
> > > }
> > > - spin_unlock(&mmu_context_lock);
> > > }
> > >
> > > static void pte_frag_destroy(void *pte_frag)
> >
> > This hunk should be okay because the mmu_context_lock does not protect
> > the extended_id array, right Aneesh?
>
> That's my understanding. The code today does this:
>
> static inline int alloc_extended_context(struct mm_struct *mm,
> unsigned long ea)
> {
> int context_id;
>
> int index = ea >> MAX_EA_BITS_PER_CONTEXT;
>
> context_id = hash__alloc_context_id();
> if (context_id < 0)
> return context_id;
>
> VM_WARN_ON(mm->context.extended_id[index]);
> mm->context.extended_id[index] = context_id;
>
> so it's not currently protected by this lock. I suppose we are currently
> protected from destroy_contexts() being called twice simultaneously, but
> you'll notice that we don't zero the array elements in destroy_contexts(),
> so if we somehow had a code path which could call it concurrently, we'd
> be seeing warnings when the second caller tried to remove the context

Yeah that'd be an existing bug.

> IDs from the IDA. I deduced that something else must be preventing
> this situation from occurring (like, oh i don't know, this function only
> being called on process exit, so implicitly only called once per context).

I think that's exactly right.

Thanks,
Nick