History

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.

Dani Liberman committed 5 years ago

Commit b2faac31 parent fae13261 file · +36 −35Browse files

Unified · Split

drivers/misc/habanalabs/common/command_submission.c+36−35
@@ -2382,47 +2382,48 @@ static int hl_cs_poll_fences(struct multi_cs_data *mcs_data) · 2381 unmodified lines
2382 break;2382 break;
2383 }2383 }
2384 2384
2385 /*2385 switch (status) {
2386 * It is possible to get an old sequence numbers from user2386 case CS_WAIT_STATUS_BUSY:
2387 * which related to already completed CSs and their fences2387 /* CS did not finished, keep waiting on its QID*/
2388 * already gone. In this case, no need to consider its QID for
2389 * mcs completion.
2390 */
2391 if (fence)
2392 mcs_data->stream_master_qid_map |=2388 mcs_data->stream_master_qid_map |=
2393 fence->stream_master_qid_map;2389 fence->stream_master_qid_map;
2390 break;
2391 case CS_WAIT_STATUS_COMPLETED:
2392 /*
2393 * Using mcs_handling_done to avoid possibility of mcs_data
2394 * returns to user indicating CS completed before it finished
2395 * all of its mcs handling, to avoid race the next time the
2396 * user waits for mcs.
2397 */
2398 if (!fence->mcs_handling_done)
2399 break;
2394 2400
2395 /*2401 mcs_data->completion_bitmap |= BIT(i);
2396 * Using mcs_handling_done to avoid possibility of mcs_data2402 /*
2397 * returns to user indicating CS completed before it finished2403 * For all completed CSs we take the earliest timestamp.
2398 * all of its mcs handling, to avoid race the next time the2404 * For this we have to validate that the timestamp is
2399 * user waits for mcs.2405 * earliest of all timestamps so far.
2400 */2406 */
2401 if (status == CS_WAIT_STATUS_BUSY ||2407 if (mcs_data->update_ts &&
2402 (fence && !fence->mcs_handling_done))2408 (ktime_compare(fence->timestamp, first_cs_time) < 0))
2403 continue;2409 first_cs_time = fence->timestamp;
2404 2410 break;
2405 mcs_data->completion_bitmap |= BIT(i);2411 case CS_WAIT_STATUS_GONE:
2406
2407 /*
2408 * best effort to extract timestamp. few notes:
2409 * - if even single fence is gone we cannot extract timestamp
2410 * (as fence not exist anymore)
2411 * - for all completed CSs we take the earliest timestamp.
2412 * for this we have to validate that:
2413 * 1. given timestamp was indeed set
2414 * 2. the timestamp is earliest of all timestamps so far
2415 */
2416
2417 if (status == CS_WAIT_STATUS_GONE) {
2418 mcs_data->update_ts = false;2412 mcs_data->update_ts = false;
2419 mcs_data->gone_cs = true;2413 mcs_data->gone_cs = true;
2420 } else if (mcs_data->update_ts &&2414 /*
2421 (ktime_compare(fence->timestamp,2415 * It is possible to get an old sequence numbers from user
2422 ktime_set(0, 0)) > 0) &&2416 * which related to already completed CSs and their fences
2423 (ktime_compare(fence->timestamp, first_cs_time) < 0)) {2417 * already gone. In this case, CS set as completed but
2424 first_cs_time = fence->timestamp;2418 * no need to consider its QID for mcs completion.
2419 */
2420 mcs_data->completion_bitmap |= BIT(i);
2421 break;
2422 default:
2423 dev_err(hdev->dev, "Invalid fence status\n");
2424 return -EINVAL;
2425 }2425 }
2426
2426 }2427 }
2427 2428
2428 hl_fences_put(mcs_data->fence_arr, arr_len);2429 hl_fences_put(mcs_data->fence_arr, arr_len);