drm/edid: track invalid blocks in drm_do_get_edid()
authorJani Nikula <jani.nikula@intel.com>
Thu, 31 Mar 2022 18:45:08 +0000 (21:45 +0300)
committerJani Nikula <jani.nikula@intel.com>
Fri, 1 Apr 2022 14:44:46 +0000 (17:44 +0300)
Track invalid blocks instead of valid extensions to minimize impact on
the happy day scenario, and hide the details in the separate function.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/6215f85b01c579a44c66129d2b5f41e1ab9294de.1648752228.git.jani.nikula@intel.com
drivers/gpu/drm/drm_edid.c

index 32d9f2a..620e97a 100644 (file)
@@ -1824,9 +1824,10 @@ bool drm_edid_is_valid(struct edid *edid)
 EXPORT_SYMBOL(drm_edid_is_valid);
 
 static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-                                              int valid_extensions)
+                                              int invalid_blocks)
 {
        struct edid *new, *dest_block;
+       int valid_extensions = edid->extensions - invalid_blocks;
        int i;
 
        new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL);
@@ -2062,7 +2063,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
                              size_t len),
        void *data)
 {
-       int j, valid_extensions = 0;
+       int j, invalid_blocks = 0;
        struct edid *edid, *new, *override;
 
        override = drm_get_override_edid(connector);
@@ -2073,12 +2074,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
        if (!edid)
                return NULL;
 
-       /* if there's no extensions or no connector, we're done */
-       valid_extensions = edid->extensions;
-       if (valid_extensions == 0)
+       if (edid->extensions == 0)
                return edid;
 
-       new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+       new = krealloc(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
        if (!new)
                goto out;
        edid = new;
@@ -2095,13 +2094,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
                }
 
                if (try == 4)
-                       valid_extensions--;
+                       invalid_blocks++;
        }
 
-       if (valid_extensions != edid->extensions) {
+       if (invalid_blocks) {
                connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-               edid = edid_filter_invalid_blocks(edid, valid_extensions);
+               edid = edid_filter_invalid_blocks(edid, invalid_blocks);
        }
 
        return edid;