[SPARC64]: Make tsb_sync() mm comparison more precise.
switch_mm() changes the mm state and does a tsb_context_switch() first, then we do the cpu register state switch which changes current_thread_info() and current(). So it's safer to check the PGD physical address stored in the trap block (which will be updated by the tsb_context_switch() in switch_mm()) than current->active_mm. Technically we should never run here in between those two updates, because interrupts are disabled during the entire context switch operation. But some day we might like to leave interrupts enabled during the context switch and this change allows that to happen without any surprises. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
683aa4012f
commit
6f25f3986a
|
@ -830,9 +830,16 @@ void smp_call_function_client(int irq, struct pt_regs *regs)
|
|||
|
||||
static void tsb_sync(void *info)
|
||||
{
|
||||
struct trap_per_cpu *tp = &trap_block[raw_smp_processor_id()];
|
||||
struct mm_struct *mm = info;
|
||||
|
||||
if (current->active_mm == mm)
|
||||
/* It is not valid to test "currrent->active_mm == mm" here.
|
||||
*
|
||||
* The value of "current" is not changed atomically with
|
||||
* switch_mm(). But that's OK, we just need to check the
|
||||
* current cpu's trap block PGD physical address.
|
||||
*/
|
||||
if (tp->pgd_paddr == __pa(mm->pgd))
|
||||
tsb_context_switch(mm);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue