for (i = 0; i < adev->sdma.num_instances; i++) if (ring == &adev->sdma.instance[i].ring ||
ring == &adev->sdma.instance[i].page) return &adev->sdma.instance[i];
return NULL;
}
int amdgpu_sdma_get_index_from_ring(struct amdgpu_ring *ring, uint32_t *index)
{ struct amdgpu_device *adev = ring->adev; int i;
for (i = 0; i < adev->sdma.num_instances; i++) { if (ring == &adev->sdma.instance[i].ring ||
ring == &adev->sdma.instance[i].page) {
*index = i; return0;
}
}
return -EINVAL;
}
uint64_t amdgpu_sdma_get_csa_mc_addr(struct amdgpu_ring *ring, unsignedint vmid)
{ struct amdgpu_device *adev = ring->adev;
uint64_t csa_mc_addr;
uint32_t index = 0; int r;
/* don't enable OS preemption on SDMA under SRIOV */ if (amdgpu_sriov_vf(adev) || vmid == 0 || !adev->gfx.mcbp) return0;
r = amdgpu_sdma_get_index_from_ring(ring, &index);
if (r || index > 31)
csa_mc_addr = 0; else
csa_mc_addr = amdgpu_csa_vaddr(adev) +
AMDGPU_CSA_SDMA_OFFSET +
index * AMDGPU_CSA_SDMA_SIZE;
return csa_mc_addr;
}
int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
{ int r, i;
r = amdgpu_ras_block_late_init(adev, ras_block); if (r) return r;
if (amdgpu_ras_is_supported(adev, ras_block->block)) { for (i = 0; i < adev->sdma.num_instances; i++) {
r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq,
AMDGPU_SDMA_IRQ_INSTANCE0 + i); if (r) goto late_fini;
}
}
err = amdgpu_sdma_init_inst_ctx(&adev->sdma.instance[instance]); if (err) goto out;
if (duplicate) { for (i = 1; i < adev->sdma.num_instances; i++)
memcpy((void *)&adev->sdma.instance[i],
(void *)&adev->sdma.instance[0], sizeof(struct amdgpu_sdma_instance));
}
/* If not define special ras_late_init function, use default ras_late_init */ if (!ras->ras_block.ras_late_init)
ras->ras_block.ras_late_init = amdgpu_sdma_ras_late_init;
/* If not defined special ras_cb function, use default ras_cb */ if (!ras->ras_block.ras_cb)
ras->ras_block.ras_cb = amdgpu_sdma_process_ras_data_cb;
/* Determine the number of rings per SDMA instance *(1forsdmagfxring,2ifpagequeueexists)
*/ if (adev->sdma.has_page_queue)
num_ring = 2; else
num_ring = 1;
/* Calculate the maximum possible mask value *basedonthenumberofSDMAinstancesandrings
*/
mask = BIT_ULL(adev->sdma.num_instances * num_ring) - 1;
if ((val & mask) == 0) return -EINVAL;
for (i = 0; i < adev->sdma.num_instances; ++i) {
ring = &adev->sdma.instance[i].ring; if (adev->sdma.has_page_queue)
page = &adev->sdma.instance[i].page; if (val & BIT_ULL(i * num_ring))
ring->sched.ready = true; else
ring->sched.ready = false;
if (page) { if (val & BIT_ULL(i * num_ring + 1))
page->sched.ready = true; else
page->sched.ready = false;
}
} /* publish sched.ready flag update effective immediately across smp */
smp_rmb(); return0;
}
/* Determine the number of rings per SDMA instance *(1forsdmagfxring,2ifpagequeueexists)
*/ if (adev->sdma.has_page_queue)
num_ring = 2; else
num_ring = 1;
for (i = 0; i < adev->sdma.num_instances; ++i) {
ring = &adev->sdma.instance[i].ring; if (adev->sdma.has_page_queue)
page = &adev->sdma.instance[i].page;
if (!caller_handles_kernel_queues) { /* Stop the scheduler's work queue for the GFX and page rings if they are running. *Thisensuresthatnonewtasksaresubmittedtothequeueswhile *theresetisinprogress.
*/
drm_sched_wqueue_stop(&gfx_ring->sched);
if (adev->sdma.has_page_queue)
drm_sched_wqueue_stop(&page_ring->sched);
}
if (sdma_instance->funcs->stop_kernel_queue) {
sdma_instance->funcs->stop_kernel_queue(gfx_ring); if (adev->sdma.has_page_queue)
sdma_instance->funcs->stop_kernel_queue(page_ring);
}
/* Perform the SDMA reset for the specified instance */
ret = amdgpu_sdma_soft_reset(adev, instance_id); if (ret) {
dev_err(adev->dev, "Failed to reset SDMA logical instance %u\n", instance_id); gotoexit;
}
if (sdma_instance->funcs->start_kernel_queue) {
sdma_instance->funcs->start_kernel_queue(gfx_ring); if (adev->sdma.has_page_queue)
sdma_instance->funcs->start_kernel_queue(page_ring);
}
exit: if (!caller_handles_kernel_queues) { /* Restart the scheduler's work queue for the GFX and page rings *iftheywerestoppedbythisfunction.Thisallowsnewtasks *tobesubmittedtothequeuesaftertheresetiscomplete.
*/ if (!ret) {
amdgpu_fence_driver_force_completion(gfx_ring);
drm_sched_wqueue_start(&gfx_ring->sched); if (adev->sdma.has_page_queue) {
amdgpu_fence_driver_force_completion(page_ring);
drm_sched_wqueue_start(&page_ring->sched);
}
}
}
mutex_unlock(&sdma_instance->engine_reset_mutex);
return ret;
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.15Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-02)
¤
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.