X-Git-Url: http://git.monstr.eu/?a=blobdiff_plain;f=kernel%2Fexit.c;h=3594291a854286545de8c33048bb57396871b083;hb=dea8dcf2a9fa8cc540136a6cd885c3beece16ec3;hp=1f236ed375f83c2bf6b3c88c65d94d6ac9b2c0b3;hpb=5b2fc08c455bbf749489254a81baeffdf4c0a693;p=linux-2.6-microblaze.git diff --git a/kernel/exit.c b/kernel/exit.c index 1f236ed375f8..3594291a8542 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -478,10 +478,24 @@ static void exit_mm(void) BUG_ON(mm != current->active_mm); /* more a memory barrier than a real lock */ task_lock(current); + /* + * When a thread stops operating on an address space, the loop + * in membarrier_private_expedited() may not observe that + * tsk->mm, and the loop in membarrier_global_expedited() may + * not observe a MEMBARRIER_STATE_GLOBAL_EXPEDITED + * rq->membarrier_state, so those would not issue an IPI. + * Membarrier requires a memory barrier after accessing + * user-space memory, before clearing tsk->mm or the + * rq->membarrier_state. + */ + smp_mb__after_spinlock(); + local_irq_disable(); current->mm = NULL; - mmap_read_unlock(mm); + membarrier_update_current_mm(NULL); enter_lazy_tlb(mm, current); + local_irq_enable(); task_unlock(current); + mmap_read_unlock(mm); mm_update_next_owner(mm); mmput(mm); if (test_thread_flag(TIF_MEMDIE))