drm/amdkfd: Eliminate get_atc_vmid_pasid_mapping_valid
get_atc_vmid_pasid_mapping_valid() is very similar to get_atc_vmid_pasid_mapping_pasid(), so they can be merged into a new function get_atc_vmid_pasid_mapping_info() to reduce register access times. More importantly, getting the PASID and the valid bit atomically with a single read fixes some potential race conditions where the mapping changes between the two reads. Signed-off-by: Yong Zhao <Yong.Zhao@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -33,7 +33,9 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
|
||||
const struct cik_ih_ring_entry *ihre =
|
||||
(const struct cik_ih_ring_entry *)ih_ring_entry;
|
||||
const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
|
||||
unsigned int vmid, pasid;
|
||||
unsigned int vmid;
|
||||
uint16_t pasid;
|
||||
bool ret;
|
||||
|
||||
/* This workaround is due to HW/FW limitation on Hawaii that
|
||||
* VMID and PASID are not written into ih_ring_entry
|
||||
@@ -48,13 +50,13 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
|
||||
*tmp_ihre = *ihre;
|
||||
|
||||
vmid = f2g->read_vmid_from_vmfault_reg(dev->kgd);
|
||||
pasid = f2g->get_atc_vmid_pasid_mapping_pasid(dev->kgd, vmid);
|
||||
ret = f2g->get_atc_vmid_pasid_mapping_info(dev->kgd, vmid, &pasid);
|
||||
|
||||
tmp_ihre->ring_id &= 0x000000ff;
|
||||
tmp_ihre->ring_id |= vmid << 8;
|
||||
tmp_ihre->ring_id |= pasid << 16;
|
||||
|
||||
return (pasid != 0) &&
|
||||
return ret && (pasid != 0) &&
|
||||
vmid >= dev->vm_info.first_vmid_kfd &&
|
||||
vmid <= dev->vm_info.last_vmid_kfd;
|
||||
}
|
||||
|
@@ -761,6 +761,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
|
||||
{
|
||||
int status = 0;
|
||||
unsigned int vmid;
|
||||
uint16_t queried_pasid;
|
||||
union SQ_CMD_BITS reg_sq_cmd;
|
||||
union GRBM_GFX_INDEX_BITS reg_gfx_index;
|
||||
struct kfd_process_device *pdd;
|
||||
@@ -782,14 +783,13 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
|
||||
*/
|
||||
|
||||
for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) {
|
||||
if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid
|
||||
(dev->kgd, vmid)) {
|
||||
if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_pasid
|
||||
(dev->kgd, vmid) == p->pasid) {
|
||||
pr_debug("Killing wave fronts of vmid %d and pasid 0x%x\n",
|
||||
vmid, p->pasid);
|
||||
break;
|
||||
}
|
||||
status = dev->kfd2kgd->get_atc_vmid_pasid_mapping_info
|
||||
(dev->kgd, vmid, &queried_pasid);
|
||||
|
||||
if (status && queried_pasid == p->pasid) {
|
||||
pr_debug("Killing wave fronts of vmid %d and pasid 0x%x\n",
|
||||
vmid, p->pasid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user