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.
Unified · Split
| @@ -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 user | 2386 | case CS_WAIT_STATUS_BUSY: |
| 2387 | * which related to already completed CSs and their fences | 2387 | /* 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_data | 2402 | /* |
| 2397 | * returns to user indicating CS completed before it finished | 2403 | * For all completed CSs we take the earliest timestamp. |
| 2398 | * all of its mcs handling, to avoid race the next time the | 2404 | * 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); |