diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 4391eb22ddb810cc674884d6b9186a674aefa6b5..5bc291c11e9bebc7aecd1d8b3cb1c7838f05c8b8 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1346,7 +1346,14 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) spin_unlock(&hdev->reset_info.lock); return 0; } + + /* This still allows the completion of some KDMA ops + * Update this before in_reset because is_in_soft_reset implies we are in reset + */ + hdev->reset_info.is_in_soft_reset = !hard_reset; + hdev->reset_info.in_reset = 1; + spin_unlock(&hdev->reset_info.lock); if (delay_reset) @@ -1354,9 +1361,6 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) handle_reset_trigger(hdev, flags); - /* This still allows the completion of some KDMA ops */ - hdev->reset_info.is_in_soft_reset = !hard_reset; - /* This also blocks future CS/VM/JOB completion operations */ hdev->disabled = true; @@ -1565,7 +1569,7 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) } spin_lock(&hdev->reset_info.lock); - hdev->reset_info.is_in_soft_reset = false; + hdev->reset_info.is_in_soft_reset = 0; /* Schedule hard reset only if requested and if not already in hard reset. * We keep 'in_reset' enabled, so no other reset can go in during the hard @@ -1612,18 +1616,22 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) out_err: hdev->disabled = true; - hdev->reset_info.is_in_soft_reset = false; + + spin_lock(&hdev->reset_info.lock); + hdev->reset_info.is_in_soft_reset = 0; if (hard_reset) { dev_err(hdev->dev, "Failed to reset! Device is NOT usable\n"); hdev->reset_info.hard_reset_cnt++; } else if (reset_upon_device_release) { + spin_unlock(&hdev->reset_info.lock); dev_err(hdev->dev, "Failed to reset device after user release\n"); flags |= HL_DRV_RESET_HARD; flags &= ~HL_DRV_RESET_DEV_RELEASE; hard_reset = true; goto again; } else { + spin_unlock(&hdev->reset_info.lock); dev_err(hdev->dev, "Failed to do soft-reset\n"); hdev->reset_info.soft_reset_cnt++; flags |= HL_DRV_RESET_HARD; @@ -1633,6 +1641,8 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) hdev->reset_info.in_reset = 0; + spin_unlock(&hdev->reset_info.lock); + return rc; }