<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Mitul,</p>
    <div class="moz-cite-prefix">On 3/28/2025 10:39 AM, Mitul Golani
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:20250328050959.659508-2-mitulkumar.ajitkumar.golani@intel.com">
      <pre wrap="" class="moz-quote-pre">Reduce false failures while preserving timing accuracy. Introduce
a small tolerance buffer based on refresh rate which accounts for
HW/SW latency without compromising validation on HRR panel.

--v2:
- correct refresh rate criteria.

Signed-off-by: Mitul Golani <a class="moz-txt-link-rfc2396E" href="mailto:mitulkumar.ajitkumar.golani@intel.com"><mitulkumar.ajitkumar.golani@intel.com></a>
---
 tests/kms_vrr.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c
index c4bb30f6a..c7be37ff8 100644
--- a/tests/kms_vrr.c
+++ b/tests/kms_vrr.c
@@ -410,6 +410,52 @@ do_flip(data_t *data, igt_fb_t *fb)
        igt_reset_timeout();
 }
 
+static void
+calculate_tolerance(uint64_t *threshold_hi, uint64_t *threshold_lo, uint64_t rates_ns)
+{
+       uint32_t refresh_rate = NSECS_PER_SEC/rates_ns;
+
+       if (refresh_rate < 0)
+               return;
+
+       /*
+        * Current IGT implementation follows this sequence:
+        * 1. Perform a page flip (`do_flip`).
+        * 2. Wait for the flip completion event.
+        * 3. Compare the timestamp of the flip completion event with the previous frame’s completion timestamp.
+        * 4. Adjust CPU cycle burning based on the relative frame time.
+        *
+        * If a flip completes too early or too late, it is marked as out of tolerance.
+        * As a result, additional CPU cycles are burned to match the `target_ns`.
+        * Even if the next frame is on time, the total frame time now includes:
+        * Burned CPU cycle time (from the previous frame) + Flip completion event time.
+        * This leads to miscalculation, causing **false out-of-range detections**.
+        * The impact is more significant on High Refresh Rate (HRR) panels, where: The allowed tolerance
+        * window is smaller and more correction time is required. i.e. for 210hz (4.762ms), allowed range is
+        * 209hz(4.784ms) to 211hz(4.739ms). This comes just 23 microsecond tolerance, which is much lesser
+        * for accounting HW/SW latency, CPU burn cycle latency and correction logic applied in igt for
+        * validation.
+        *
+        * To address this implement a Bucketing Strategy:
+        * Provide a small tolerance buffer to allow IGT tests to account for correction. based on range of
+        * asked refresh rate. This prevents excessive failures due to minor timing adjustments.
+        * Although an imperical number but already IGT is living with that.
+        * This also ensures that asked refresh rate is not too off and always catch the real HW/software 
+        * latencies.
+        */
+
+       if (refresh_rate <= 120) {</pre>
    </blockquote>
    remove = in this if condition <span style="white-space: pre-wrap">if (refresh_rate < 120)</span>
    <blockquote type="cite" cite="mid:20250328050959.659508-2-mitulkumar.ajitkumar.golani@intel.com">
      <pre wrap="" class="moz-quote-pre">
+               *threshold_hi = NSECS_PER_SEC / (((float)NSECS_PER_SEC / rates_ns) + 1);
+               *threshold_lo = NSECS_PER_SEC / (((float)NSECS_PER_SEC / rates_ns) - 1);
+       } else if (refresh_rate >= 120 && refresh_rate <= 240) {
+               *threshold_hi = NSECS_PER_SEC / (((float)NSECS_PER_SEC / rates_ns) + 5);
+               *threshold_lo = NSECS_PER_SEC / (((float)NSECS_PER_SEC / rates_ns) - 5);
+       } else {
+               *threshold_hi = NSECS_PER_SEC / (((float)NSECS_PER_SEC / rates_ns) + 10);
+               *threshold_lo = NSECS_PER_SEC / (((float)NSECS_PER_SEC / rates_ns) - 10);
+       }
+}</pre>
    </blockquote>
    Patch has style problems please check by running checkpatch.pl.<br>
    <br>
    imho, Better to add one more bucket for refresh rate between 60 to
    120 to +/-2 deviation range.<br>
    <p>from my analysis below observed,</p>
    <p>from (60 -140) flips are in deviation range of 2, from (140 -220)
      flips are in deviation range of 5 and after 220 flips are in
      deviation range of 10.  </p>
    <table border="0" cellpadding="0" cellspacing="0" width="534">
      <colgroup><col width="64" span="3" style="width:48pt"> <col width="82" span="2" style="mso-width-source:userset;mso-width-alt:2862;
 width:62pt"> <col width="89" span="2" style="mso-width-source:userset;mso-width-alt:3118;
 width:67pt"> </colgroup><tbody>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl66" width="64" style="height:14.5pt;width:48pt"> </td>
          <td class="xl66" width="64" style="border-left:none;width:48pt"> </td>
          <td class="xl66" width="64" style="border-left:none;width:48pt"> </td>
          <td colspan="4" class="xl67" width="342" style="border-left:none;width:258pt">Number of flips on
            threshold</td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl66" style="height:14.5pt;border-top:none">SNO</td>
          <td class="xl66" style="border-top:none;border-left:none">RR</td>
          <td class="xl66" style="border-top:none;border-left:none">Total
            flips</td>
          <td class="xl66" align="right" style="border-top:none;border-left:none">1</td>
          <td class="xl66" align="right" style="border-top:none;border-left:none">2</td>
          <td class="xl66" align="right" style="border-top:none;border-left:none">5</td>
          <td class="xl66" align="right" style="border-top:none;border-left:none">10</td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">1</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">62</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">311</td>
          <td class="xl65" style="border-top:none;border-left:none">307(98.7%)</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">2</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">94</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">471</td>
          <td class="xl65" style="border-top:none;border-left:none">291(61.78%)</td>
          <td class="xl65" style="border-top:none;border-left:none">458(97.24%)</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">3</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">126</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">631</td>
          <td class="xl65" style="border-top:none;border-left:none">447(70.84%)</td>
          <td class="xl65" style="border-top:none;border-left:none">587(93.02%)</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">4</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">158</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">791</td>
          <td class="xl65" style="border-top:none;border-left:none">257(32.50%)</td>
          <td class="xl65" style="border-top:none;border-left:none">521(65.86%)</td>
          <td class="xl65" style="border-top:none;border-left:none">788(99.62%)</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">5</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">190</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">951</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none">504(52.99%)</td>
          <td class="xl65" style="border-top:none;border-left:none">907(95.37%)</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">6</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">222</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">1111</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none">802(72.18%)</td>
          <td class="xl65" style="border-top:none;border-left:none">1083(97.48%)</td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">7</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">254</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">1271</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none">1022(80.40%)</td>
          <td class="xl65" style="border-top:none;border-left:none">1249(98.26%)</td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">8</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">286</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">1431</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none">675(47.16%)</td>
          <td class="xl65" style="border-top:none;border-left:none">1160(81.06%)</td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">9</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">318</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">1591</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none">892(56.06%)</td>
          <td class="xl65" style="border-top:none;border-left:none">1393(87.56%)</td>
        </tr>
        <tr height="19" style="height:14.5pt">
          <td height="19" class="xl65" align="right" style="height:14.5pt;border-top:none">10</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">350</td>
          <td class="xl65" align="right" style="border-top:none;border-left:none">1751</td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none"> </td>
          <td class="xl65" style="border-top:none;border-left:none">739(42.18%)</td>
          <td class="xl65" style="border-top:none;border-left:none">1591(90.81%)</td>
        </tr>
      </tbody>
    </table>
    <br>
    <br>
    <br>
    <blockquote type="cite" cite="mid:20250328050959.659508-2-mitulkumar.ajitkumar.golani@intel.com">
      <pre wrap="" class="moz-quote-pre">
+
 /*
  * Flips at the given rate and measures against the expected value.
  * Returns the pass rate as a percentage from 0 - 100.
@@ -439,9 +485,7 @@ flip_and_measure(data_t *data, igt_output_t *output, enum pipe pipe,
                else
                        exp_rate_ns = vtest_ns.max;
 
-               /* Allow ~1 Hz deviation for different reasons causing delay. */
-               threshold_hi[i] = NSECS_PER_SEC / (((float)NSECS_PER_SEC / exp_rate_ns) + 1);
-               threshold_lo[i] = NSECS_PER_SEC / (((float)NSECS_PER_SEC / exp_rate_ns) - 1);
+               calculate_tolerance(&threshold_hi[i], &threshold_lo[i], exp_rate_ns);
 
                igt_info("Requested rate[%d]: %"PRIu64" ns, Expected rate between: %"PRIu64" ns to %"PRIu64" ns\n",
                                i, rates_ns[i], threshold_hi[i], threshold_lo[i]);
</pre>
    </blockquote>
  </body>
</html>