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:
Dani Liberman
2021-10-12 13:30:27 +03:00
committed by Oded Gabbay
parent fae132632c
commit b2faac3887

View File

@ -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);