From 992e418dd945755fe947c8df7329e71e76b9e4f8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 14 Jan 2017 00:28:23 +0000 Subject: [PATCH] drm/i915: Compact memcmp in i915_vma_compare() In preparation for the next patch to convert to using an anonymous union and leaving the excess bytes in the union uninitialised, we first need to make sure we do not compare using those uninitialised bytes. We also want to preserve the compactness of the code, avoiding a second call to memcmp or introducing a switch, so we take advantage of using the type as an encoded size (as well as a unique identifier for each type of view). v2: Add the rationale for why we encode size into ggtt_view.type as a comment before the memcmp() v3: Use a switch to also assert that no two i915_ggtt_view_type have the same value. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/20170114002827.31315-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.h | 28 +++++++++++++++++++++------- drivers/gpu/drm/i915/i915_vma.h | 20 ++++++++++++++------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 334b61b..35ea4a1 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -145,12 +145,6 @@ typedef uint64_t gen8_ppgtt_pml4e_t; struct sg_table; -enum i915_ggtt_view_type { - I915_GGTT_VIEW_NORMAL = 0, - I915_GGTT_VIEW_ROTATED, - I915_GGTT_VIEW_PARTIAL, -}; - struct intel_rotation_info { struct intel_rotation_plane_info { /* tiles */ @@ -173,10 +167,30 @@ static inline void assert_intel_partial_info_is_packed(void) BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int)); } +enum i915_ggtt_view_type { + I915_GGTT_VIEW_NORMAL = 0, + I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info), + I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info), +}; + +static inline void assert_i915_ggtt_view_type_is_unique(void) +{ + /* As we encode the size of each branch inside the union into its type, + * we have to be careful that each branch has a unique size. + */ + switch ((enum i915_ggtt_view_type)0) { + case I915_GGTT_VIEW_NORMAL: + case I915_GGTT_VIEW_PARTIAL: + case I915_GGTT_VIEW_ROTATED: + /* gcc complains if these are identical cases */ + break; + } +} + struct i915_ggtt_view { enum i915_ggtt_view_type type; - union { + /* Members need to contain no holes/padding */ struct intel_partial_info partial; struct intel_rotation_info rotated; } params; diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 008cf11..fdbacc0 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -199,15 +199,23 @@ i915_vma_compare(struct i915_vma *vma, if (cmp) return cmp; + BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL != 0); + cmp = vma->ggtt_view.type; if (!view) - return vma->ggtt_view.type; + return cmp; - if (vma->ggtt_view.type != view->type) - return vma->ggtt_view.type - view->type; + cmp -= view->type; + if (cmp) + return cmp; - return memcmp(&vma->ggtt_view.params, - &view->params, - sizeof(view->params)); + /* ggtt_view.type also encodes its size so that we both distinguish + * different views using it as a "type" and also use a compact (no + * accessing of uninitialised padding bytes) memcmp without storing + * an extra parameter or adding more code. + */ + BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL); + BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED); + return memcmp(&vma->ggtt_view.params, &view->params, view->type); } int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, -- 2.7.4