drm/xe/rtp: Do not break parsing when missing context

With the current implementation, the RTP framework will cause parsing of
the rule set to be interrupted if one rule requires a context item (gt
or hwe) that is missing (i.e. when the value is NULL).

This is arguably a semantic error instead of a syntactic one, meaning
that RTP should not interrupt parsing the rules.  With the current
behavior, we would miss detecting other errors that could appear in the
remaining rules and could also prevent valid rules joined by "OR" from
being evaluated.

Make sure that we do not stop parsing the rule set when detecting
missing context and let's add rtp_rules_test_cases to reflect that.

v2:
  - Add "missing-context" in the test case names to indicate that those
    are about rules that are missing the necessary context. (Matt)
  - Rebase: treat the new match type XE_RTP_MATCH_PLATFORM_STEP in the
    same way when the platform is missing step information.

Reviewed-by: Matt Roper <matthew.d.roper@intel.com> # v1
Link: https://patch.msgid.link/20260522-rtp-rule-parser-v3-4-0c51039899f4@intel.com
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
This commit is contained in:
Gustavo Sousa 2026-05-22 05:45:19 -03:00
parent f6d460e33e
commit 6dc0763213
2 changed files with 72 additions and 22 deletions

View File

@ -238,6 +238,34 @@ static const struct rtp_rules_test_case rtp_rules_cases[] = {
.expected_err = -EINVAL,
XE_RTP_RULES(FUNC(match_no), OR, OR, FUNC(match_no)),
},
/* No match because hwe is NULL. */
{
.name = "missing-context-engine-class",
.expected_match = false,
XE_RTP_RULES(ENGINE_CLASS(RENDER)),
},
/*
* Missing context (hwe==NULL) does not cause parsing to stop, hence we
* expect a match.
*/
{
.name = "missing-context-engine-class-or-yes",
.expected_match = true,
XE_RTP_RULES(ENGINE_CLASS(RENDER), OR, FUNC(match_yes)),
},
/*
* Missing context (hwe==NULL) does not cause parsing to stop, hence we
* expect a syntax error.
*/
{
.name = "missing-context-engine-class-or-or-yes",
.expected_match = true,
.expected_err = -EINVAL,
XE_RTP_RULES(ENGINE_CLASS(RENDER), OR, OR, FUNC(match_yes)),
},
};
static void xe_rtp_rules_tests(struct kunit *test)

View File

@ -67,67 +67,85 @@ static bool rule_matches_with_err(const struct xe_device *xe,
xe->info.subplatform == r->subplatform;
break;
case XE_RTP_MATCH_PLATFORM_STEP:
if (drm_WARN_ON(&xe->drm, xe->info.step.platform == STEP_NONE))
goto error;
if (drm_WARN_ON(&xe->drm, xe->info.step.platform == STEP_NONE)) {
match = false;
break;
}
match = xe->info.step.platform >= r->step_start &&
xe->info.step.platform < r->step_end;
break;
case XE_RTP_MATCH_GRAPHICS_VERSION:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.graphics_verx100 == r->ver_start &&
(!has_samedia(xe) || !xe_gt_is_media_type(gt));
break;
case XE_RTP_MATCH_GRAPHICS_VERSION_RANGE:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.graphics_verx100 >= r->ver_start &&
xe->info.graphics_verx100 <= r->ver_end &&
(!has_samedia(xe) || !xe_gt_is_media_type(gt));
break;
case XE_RTP_MATCH_GRAPHICS_VERSION_ANY_GT:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.graphics_verx100 == r->ver_start;
break;
case XE_RTP_MATCH_GRAPHICS_STEP:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.step.graphics >= r->step_start &&
xe->info.step.graphics < r->step_end &&
(!has_samedia(xe) || !xe_gt_is_media_type(gt));
break;
case XE_RTP_MATCH_MEDIA_VERSION:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.media_verx100 == r->ver_start &&
(!has_samedia(xe) || xe_gt_is_media_type(gt));
break;
case XE_RTP_MATCH_MEDIA_VERSION_RANGE:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.media_verx100 >= r->ver_start &&
xe->info.media_verx100 <= r->ver_end &&
(!has_samedia(xe) || xe_gt_is_media_type(gt));
break;
case XE_RTP_MATCH_MEDIA_STEP:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.step.media >= r->step_start &&
xe->info.step.media < r->step_end &&
(!has_samedia(xe) || xe_gt_is_media_type(gt));
break;
case XE_RTP_MATCH_MEDIA_VERSION_ANY_GT:
if (drm_WARN_ON(&xe->drm, !gt))
goto error;
if (drm_WARN_ON(&xe->drm, !gt)) {
match = false;
break;
}
match = xe->info.media_verx100 == r->ver_start;
break;
@ -138,14 +156,18 @@ static bool rule_matches_with_err(const struct xe_device *xe,
match = xe->info.is_dgfx;
break;
case XE_RTP_MATCH_ENGINE_CLASS:
if (drm_WARN_ON(&xe->drm, !hwe))
goto error;
if (drm_WARN_ON(&xe->drm, !hwe)) {
match = false;
break;
}
match = hwe->class == r->engine_class;
break;
case XE_RTP_MATCH_NOT_ENGINE_CLASS:
if (drm_WARN_ON(&xe->drm, !hwe))
goto error;
if (drm_WARN_ON(&xe->drm, !hwe)) {
match = false;
break;
}
match = hwe->class != r->engine_class;
break;