/* * Most if the context management is out of line
*/ #define init_new_context init_new_context externint init_new_context(struct task_struct *tsk, struct mm_struct *mm); #define destroy_context destroy_context externvoid destroy_context(struct mm_struct *mm); #ifdef CONFIG_SPAPR_TCE_IOMMU struct mm_iommu_table_group_mem_t;
staticinlinevoid mm_context_add_copro(struct mm_struct *mm)
{ /* * If any copro is in use, increment the active CPU count * in order to force TLB invalidations to be global as to * propagate to the Nest MMU.
*/ if (atomic_inc_return(&mm->context.copros) == 1)
inc_mm_active_cpus(mm);
}
staticinlinevoid mm_context_remove_copro(struct mm_struct *mm)
{ int c;
/* * When removing the last copro, we need to broadcast a global * flush of the full mm, as the next TLBI may be local and the * nMMU and/or PSL need to be cleaned up. * * Both the 'copros' and 'active_cpus' counts are looked at in * radix__flush_all_mm() to determine the scope (local/global) * of the TLBIs, so we need to flush first before decrementing * 'copros'. If this API is used by several callers for the * same context, it can lead to over-flushing. It's hopefully * not common enough to be a problem. * * Skip on hash, as we don't know how to do the proper flush * for the time being. Invalidations will remain global if * used on hash. Note that we can't drop 'copros' either, as * it could make some invalidations local with no flush * in-between.
*/ if (radix_enabled()) {
radix__flush_all_mm(mm);
c = atomic_dec_if_positive(&mm->context.copros); /* Detect imbalance between add and remove */
WARN_ON(c < 0);
if (c == 0)
dec_mm_active_cpus(mm);
}
}
/* * vas_windows counter shows number of open windows in the mm * context. During context switch, use this counter to clear the * foreign real address mapping (CP_ABORT) for the thread / process * that intend to use COPY/PASTE. When a process closes all windows, * disable CP_ABORT which is expensive to run. * * For user context, register a copro so that TLBIs are seen by the * nest MMU. mm_context_add/remove_vas_window() are used only for user * space windows.
*/ staticinlinevoid mm_context_add_vas_window(struct mm_struct *mm)
{
atomic_inc(&mm->context.vas_windows);
mm_context_add_copro(mm);
}
staticinlinevoid mm_context_remove_vas_window(struct mm_struct *mm)
{ int v;
mm_context_remove_copro(mm);
v = atomic_dec_if_positive(&mm->context.vas_windows);
/* * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings.
*/ #define activate_mm activate_mm staticinlinevoid activate_mm(struct mm_struct *prev, struct mm_struct *next)
{
switch_mm_irqs_off(prev, next, current);
}
/* We don't currently use enter_lazy_tlb() for anything */ #ifdef CONFIG_PPC_BOOK3E_64 #define enter_lazy_tlb enter_lazy_tlb staticinlinevoid enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{ /* 64-bit Book3E keeps track of current PGD in the PACA */
get_paca()->pgd = NULL;
} #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.