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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
Reference in New Issue
Block a user