/** * hl_mmu_v2_hr_init() - initialize the MMU module. * @hdev: habanalabs device structure. * * This function does the following: * - Create a pool of pages for pgt_infos. * - Create a shadow table for pgt * * Return: 0 for success, non-zero for failure.
*/ staticinlineint hl_mmu_v2_hr_init(struct hl_device *hdev)
{ struct asic_fixed_properties *prop = &hdev->asic_prop;
/** * hl_mmu_v2_hr_fini() - release the MMU module. * @hdev: habanalabs device structure. * * This function does the following: * - Disable MMU in H/W. * - Free the pgt_infos pool. * * All contexts should be freed before calling this function.
*/ staticinlinevoid hl_mmu_v2_hr_fini(struct hl_device *hdev)
{ struct asic_fixed_properties *prop = &hdev->asic_prop;
/** * hl_mmu_v2_hr_ctx_init() - initialize a context for using the MMU module. * @ctx: pointer to the context structure to initialize. * * Initialize a mutex to protect the concurrent mapping flow, a hash to hold all * page tables hops related to this context. * Return: 0 on success, non-zero otherwise.
*/ staticint hl_mmu_v2_hr_ctx_init(struct hl_ctx *ctx)
{
hash_init(ctx->hr_mmu_phys_hash); return 0;
}
/* * hl_mmu_v2_hr_ctx_fini - disable a ctx from using the mmu module * * @ctx: pointer to the context structure * * This function does the following: * - Free any pgts which were not freed yet * - Free the mutex * - Free DRAM default page mapping hops
*/ staticvoid hl_mmu_v2_hr_ctx_fini(struct hl_ctx *ctx)
{ struct hl_device *hdev = ctx->hdev; struct pgt_info *pgt_info; struct hlist_node *tmp; int i;
if (!hash_empty(ctx->hr_mmu_phys_hash))
dev_err(hdev->dev, "ctx %d is freed while it has pgts in use\n",
ctx->asid);
hash_for_each_safe(ctx->hr_mmu_phys_hash, i, tmp, pgt_info, node) {
dev_err_ratelimited(hdev->dev, "pgt_info of addr 0x%llx of asid %d was not destroyed, num_ptes: %d\n",
pgt_info->phys_addr, ctx->asid, pgt_info->num_of_ptes);
hl_mmu_hr_free_hop_remove_pgt(pgt_info, &ctx->hdev->mmu_priv.hr,
ctx->hdev->asic_prop.pmmu.hop_table_size);
}
}
/* shifts and masks are the same in PMMU and HMMU, use one of them */
mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu;
hop_last = mmu_prop->num_hops - 1;
for (i = 0 ; i < mmu_prop->num_hops ; i++) { /* we get HOP0 differently, it doesn't need curr_pte */ if (i == 0)
hops_pgt_info[i] = hl_mmu_v2_hr_get_hop0_pgt_info(ctx); else
hops_pgt_info[i] = hl_mmu_hr_get_next_hop_pgt_info(ctx,
&ctx->hdev->mmu_func[MMU_HR_PGT].hr_funcs, curr_pte); if (!hops_pgt_info[i]) goto not_mapped;
hop_pte_phys_addr[i] = hl_mmu_get_hop_pte_phys_addr(ctx, mmu_prop, i,
hops_pgt_info[i]->phys_addr,
scrambled_virt_addr); if (hop_pte_phys_addr[i] == U64_MAX) return -EFAULT;
/* * This mapping function can map a page or a huge page. For huge page * there are only 4 hops rather than 5. Currently the DRAM allocation * uses huge pages only but user memory could have been allocated with * one of the two page sizes. Since this is a common code for all the * three cases, we need this hugs page check.
*/ if (is_dram_addr)
mmu_prop = &prop->dmmu; elseif (page_size == prop->pmmu_huge.page_size)
mmu_prop = &prop->pmmu_huge; else
mmu_prop = &prop->pmmu;
hop_last = hl_mmu_v2_get_last_hop(mmu_prop, page_size); if (hop_last <= 0) {
dev_err(ctx->hdev->dev, "Invalid last HOP %d\n", hop_last); return -EFAULT;
}
/* Write the PTEs */
hl_mmu_hr_write_pte(ctx, hops_pgt_info[hop_last], hop_pte_phys_addr[hop_last], curr_pte,
ctx->hdev->asic_prop.pmmu.hop_table_size);
/* for each new hop, add its address to the table of previous-hop */ for (i = 1 ; i <= hop_last ; i++) { if (hop_new[i]) {
curr_pte = (hops_pgt_info[i]->phys_addr & HOP_PHYS_ADDR_MASK) |
PAGE_PRESENT_MASK;
hl_mmu_hr_write_pte(ctx, hops_pgt_info[i - 1], hop_pte_phys_addr[i - 1],
curr_pte, ctx->hdev->asic_prop.pmmu.hop_table_size); if (i - 1)
hl_mmu_hr_get_pte(ctx, &ctx->hdev->mmu_func[MMU_HR_PGT].hr_funcs,
hops_pgt_info[i - 1]->phys_addr);
}
}
err: for (i = 1 ; i <= hop_last ; i++) if (hop_new[i] && hops_pgt_info[i])
hl_mmu_hr_free_hop_remove_pgt(hops_pgt_info[i], &ctx->hdev->mmu_priv.hr,
ctx->hdev->asic_prop.pmmu.hop_table_size);
return rc;
}
/* * hl_mmu_v2_swap_out - marks all mapping of the given ctx as swapped out * * @ctx: pointer to the context structure *
*/ staticvoid hl_mmu_v2_hr_swap_out(struct hl_ctx *ctx)
{
}
/* * hl_mmu_v2_swap_in - marks all mapping of the given ctx as swapped in * * @ctx: pointer to the context structure *
*/ staticvoid hl_mmu_v2_hr_swap_in(struct hl_ctx *ctx)
{
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.