Commit b2faac38 authored by Dani Liberman's avatar Dani Liberman Committed by Oded Gabbay
Browse files

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: default avatarDani Liberman <dliberman@habana.ai>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent fae13263
Loading
Loading
Loading
Loading
+36 −35
Original line number Original line Diff line number Diff line
@@ -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
			 * Using mcs_handling_done to avoid possibility of mcs_data
			 * returns to user indicating CS completed before it finished
			 * returns to user indicating CS completed before it finished
			 * all of its mcs handling, to avoid race the next time the
			 * all of its mcs handling, to avoid race the next time the
			 * user waits for mcs.
			 * user waits for mcs.
			 */
			 */
		if (status == CS_WAIT_STATUS_BUSY ||
			if (!fence->mcs_handling_done)
				(fence && !fence->mcs_handling_done))
				break;
			continue;


			mcs_data->completion_bitmap |= BIT(i);
			mcs_data->completion_bitmap |= BIT(i);

			/*
			/*
		 * best effort to extract timestamp. few notes:
			 * For all completed CSs we take the earliest timestamp.
		 * - if even single fence is gone we cannot extract timestamp
			 * For this we have to validate that the timestamp is
		 *   (as fence not exist anymore)
			 * earliest of all timestamps so far.
		 * - 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 (mcs_data->update_ts &&
		if (status == CS_WAIT_STATUS_GONE) {
					(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->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);