habanalabs: refactor fence handling in hl_cs_poll_fences
To avoid checking if fence exists multipled times, changed fence handling to depend only on the fence status field: Busy, which means CS still did not completed : Add its QID so multi CS wait on its completion. Finished, which means CS completed and fence exists: Raise its completion bit if it finished mcs handling and update if necessary the earliest timestamp. Gone, which means CS already completed and fence deleted: Update multi CS data to ignore timestamp and raise its completion bit. Signed-off-by: Dani Liberman <dliberman@habana.ai> Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
committed by
Oded Gabbay
parent
fae132632c
commit
b2faac3887
@ -2382,47 +2382,48 @@ static int hl_cs_poll_fences(struct multi_cs_data *mcs_data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
switch (status) {
|
||||||
* It is possible to get an old sequence numbers from user
|
case CS_WAIT_STATUS_BUSY:
|
||||||
* which related to already completed CSs and their fences
|
/* CS did not finished, keep waiting on its QID*/
|
||||||
* already gone. In this case, no need to consider its QID for
|
|
||||||
* mcs completion.
|
|
||||||
*/
|
|
||||||
if (fence)
|
|
||||||
mcs_data->stream_master_qid_map |=
|
mcs_data->stream_master_qid_map |=
|
||||||
fence->stream_master_qid_map;
|
fence->stream_master_qid_map;
|
||||||
|
break;
|
||||||
|
case CS_WAIT_STATUS_COMPLETED:
|
||||||
|
/*
|
||||||
|
* Using mcs_handling_done to avoid possibility of mcs_data
|
||||||
|
* returns to user indicating CS completed before it finished
|
||||||
|
* all of its mcs handling, to avoid race the next time the
|
||||||
|
* user waits for mcs.
|
||||||
|
*/
|
||||||
|
if (!fence->mcs_handling_done)
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
mcs_data->completion_bitmap |= BIT(i);
|
||||||
* Using mcs_handling_done to avoid possibility of mcs_data
|
/*
|
||||||
* returns to user indicating CS completed before it finished
|
* For all completed CSs we take the earliest timestamp.
|
||||||
* all of its mcs handling, to avoid race the next time the
|
* For this we have to validate that the timestamp is
|
||||||
* user waits for mcs.
|
* earliest of all timestamps so far.
|
||||||
*/
|
*/
|
||||||
if (status == CS_WAIT_STATUS_BUSY ||
|
if (mcs_data->update_ts &&
|
||||||
(fence && !fence->mcs_handling_done))
|
(ktime_compare(fence->timestamp, first_cs_time) < 0))
|
||||||
continue;
|
first_cs_time = fence->timestamp;
|
||||||
|
break;
|
||||||
mcs_data->completion_bitmap |= BIT(i);
|
case CS_WAIT_STATUS_GONE:
|
||||||
|
|
||||||
/*
|
|
||||||
* best effort to extract timestamp. few notes:
|
|
||||||
* - if even single fence is gone we cannot extract timestamp
|
|
||||||
* (as fence not exist anymore)
|
|
||||||
* - for all completed CSs we take the earliest timestamp.
|
|
||||||
* for this we have to validate that:
|
|
||||||
* 1. given timestamp was indeed set
|
|
||||||
* 2. the timestamp is earliest of all timestamps so far
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (status == CS_WAIT_STATUS_GONE) {
|
|
||||||
mcs_data->update_ts = false;
|
mcs_data->update_ts = false;
|
||||||
mcs_data->gone_cs = true;
|
mcs_data->gone_cs = true;
|
||||||
} else if (mcs_data->update_ts &&
|
/*
|
||||||
(ktime_compare(fence->timestamp,
|
* It is possible to get an old sequence numbers from user
|
||||||
ktime_set(0, 0)) > 0) &&
|
* which related to already completed CSs and their fences
|
||||||
(ktime_compare(fence->timestamp, first_cs_time) < 0)) {
|
* already gone. In this case, CS set as completed but
|
||||||
first_cs_time = fence->timestamp;
|
* no need to consider its QID for mcs completion.
|
||||||
|
*/
|
||||||
|
mcs_data->completion_bitmap |= BIT(i);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(hdev->dev, "Invalid fence status\n");
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hl_fences_put(mcs_data->fence_arr, arr_len);
|
hl_fences_put(mcs_data->fence_arr, arr_len);
|
||||||
|
Reference in New Issue
Block a user