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;
}
/*
* It is possible to get an old sequence numbers from user
* which related to already completed CSs and their fences
* already gone. In this case, no need to consider its QID for
* mcs completion.
*/
if (fence)
switch (status) {
case CS_WAIT_STATUS_BUSY:
/* CS did not finished, keep waiting on its QID*/
mcs_data->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;
/*
* 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 (status == CS_WAIT_STATUS_BUSY ||
(fence && !fence->mcs_handling_done))
continue;
mcs_data->completion_bitmap |= BIT(i);
/*
* 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->completion_bitmap |= BIT(i);
/*
* For all completed CSs we take the earliest timestamp.
* For this we have to validate that the timestamp is
* earliest of all timestamps so far.
*/
if (mcs_data->update_ts &&
(ktime_compare(fence->timestamp, first_cs_time) < 0))
first_cs_time = fence->timestamp;
break;
case CS_WAIT_STATUS_GONE:
mcs_data->update_ts = false;
mcs_data->gone_cs = true;
} else if (mcs_data->update_ts &&
(ktime_compare(fence->timestamp,
ktime_set(0, 0)) > 0) &&
(ktime_compare(fence->timestamp, first_cs_time) < 0)) {
first_cs_time = fence->timestamp;
/*
* It is possible to get an old sequence numbers from user
* which related to already completed CSs and their fences
* already gone. In this case, CS set as completed but
* 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);