/* If there were no free slots in the parent allocation before, *therewillbenow,soreturnPTPtothecache.
*/ if (!ptp->free)
list_add(&ptp->head, &mmu->ptp.list);
ptp->free |= BIT(slot);
/* If there's no more sub-allocations, destroy PTP. */ if (ptp->free == ptp->mask) {
nvkm_mmu_ptc_put(mmu, force, &ptp->pt);
list_del(&ptp->head);
kfree(ptp);
}
if (!(pt = kzalloc(sizeof(*pt), GFP_KERNEL))) return NULL;
ptp = list_first_entry_or_null(&mmu->ptp.list, typeof(*ptp), head); if (!ptp) { /* Need to allocate a new parent to sub-allocate from. */ if (!(ptp = kmalloc(sizeof(*ptp), GFP_KERNEL))) {
kfree(pt); return NULL;
}
/* Lookup cache for this page table size. */
mutex_lock(&mmu->ptc.mutex);
ptc = nvkm_mmu_ptc_find(mmu, size); if (!ptc) {
mutex_unlock(&mmu->ptc.mutex); return NULL;
}
/* If there's a free PT in the cache, reuse it. */
pt = list_first_entry_or_null(&ptc->item, typeof(*pt), head); if (pt) { if (zero)
nvkm_fo64(pt->memory, 0, 0, size >> 3);
list_del(&pt->head);
ptc->refs--;
mutex_unlock(&mmu->ptc.mutex); return pt;
}
mutex_unlock(&mmu->ptc.mutex);
/* No such luck, we need to allocate. */ if (!(pt = kmalloc(sizeof(*pt), GFP_KERNEL))) return NULL;
pt->ptc = ptc;
pt->sub = false;
ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST,
size, align, zero, &pt->memory); if (ret) {
kfree(pt); return NULL;
}
/* Non-coherent, cached, system memory. * *Block-linearmappingsofsystemmemorymustbedonethrough *BAR1,andcannotbesupportedonsystemswherewe'reunable *tomapBAR1withwrite-combining.
*/
type |= NVKM_MEM_MAPPABLE; if (!device->bar || device->bar->iomap_uncached)
nvkm_mmu_type(mmu, heap, type & ~NVKM_MEM_KIND); else
nvkm_mmu_type(mmu, heap, type);
/* Coherent, cached, system memory. * *Unsupportedonsystemsthataren'tabletosupportsnooped *mappings,andalsoforblock-linearmappingswhichmustbe *donethroughBAR1.
*/
type |= NVKM_MEM_COHERENT; if (device->func->cpu_coherent)
nvkm_mmu_type(mmu, heap, type & ~NVKM_MEM_KIND);
/* Uncached system memory. */
nvkm_mmu_type(mmu, heap, type |= NVKM_MEM_UNCACHED);
}
/* Add non-mappable VRAM types first so that they're preferred *overanythingelse.Mixed-memorywillbeslowerthanother *heaps,it'sprioritisedlast.
*/
nvkm_mmu_type(mmu, heapU, type);
nvkm_mmu_type(mmu, heapN, type);
nvkm_mmu_type(mmu, heapM, type);
/* Add host memory types next, under the assumption that users *wantingmappablememorywanttousethemasstagingbuffers *orthelike.
*/
nvkm_mmu_host(mmu);
/* Mappable VRAM types go last, as they're basically the worst *possibletypetoaskforunlessthere'snootherchoice.
*/ if (device->bar) { /* Write-combined BAR1 access. */
type |= NVKM_MEM_MAPPABLE; if (!device->bar->iomap_uncached) {
nvkm_mmu_type(mmu, heapN, type);
nvkm_mmu_type(mmu, heapM, type);
}
/* Uncached BAR1 access. */
type |= NVKM_MEM_COHERENT;
type |= NVKM_MEM_UNCACHED;
nvkm_mmu_type(mmu, heapN, type);
nvkm_mmu_type(mmu, heapM, type);
}
}
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.