From patchwork Mon Nov 19 20:23:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Egbert Eich X-Patchwork-Id: 1769061 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 4B352DF264 for ; Mon, 19 Nov 2012 20:50:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1BA82E626F for ; Mon, 19 Nov 2012 12:50:11 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTP id 41B88E6249 for ; Mon, 19 Nov 2012 12:41:30 -0800 (PST) Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 8BB22A3D59; Mon, 19 Nov 2012 21:41:29 +0100 (CET) Received: from sles11.fritz.box (sles11.fritz.box [192.168.178.22]) by debian (Postfix) with ESMTP id 41C543F2FE; Mon, 19 Nov 2012 21:41:29 +0100 (CET) From: Egbert Eich To: dri-devel@lists.freedesktop.org Subject: [PATCH 11/17] DRM/KMS/EDID: Avoid failing on krealloc on EDID blocks. Date: Mon, 19 Nov 2012 15:23:12 -0500 Message-Id: <1353356598-10634-12-git-send-email-eich@suse.de> X-Mailer: git-send-email 1.7.7 In-Reply-To: <1353356598-10634-1-git-send-email-eich@suse.de> References: <1353356598-10634-1-git-send-email-eich@suse.de> Cc: Egbert Eich , Takashi Iwai X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org There is no point to call krealloc() to shrink the amount of memory for EDID blocks: the implementation of krealloc() will ignore the size change and return the same chunk of memory anyway. So far we failed reading EDIDs when krealloc() failed. This may happen if the size required to store an EDID is larger than one page and the kernel is not able to find consecutive pages to allocate. In this case it is still better to return what we already have (in most cases the base block) and correct the extension block flag and the checksum accordingly than to fail completely. Signed-off-by: Egbert Eich --- drivers/gpu/drm/drm_edid.c | 34 +++++++++++++--------------------- 1 files changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 410a54d..16c06d6 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -387,7 +387,7 @@ fixup_blockmaps(u8 **blockp, int eblock_cnt) u8 *tmp_p; tmp_p = krealloc(block, (eblock_cnt + 2) * EDID_LENGTH, GFP_KERNEL); if (!tmp_p) - return -ENOMEM; + return eblock_cnt; *blockp = block = tmp_p; total_cnt = eblock_cnt + 1; } @@ -408,27 +408,16 @@ fixup_blockmaps(u8 **blockp, int eblock_cnt) return eblock_cnt; } -static int +static void fixup_edid(u8 **blockp, int valid_extensions) { - u8 *new = NULL; - - if (valid_extensions != (*blockp)[EDID_EXTENSION_FLAG_OFFSET]) { - + if (valid_extensions != (*blockp)[EDID_EXTENSION_FLAG_OFFSET]) { if (valid_extensions) valid_extensions = fixup_blockmaps(blockp, valid_extensions); - if (valid_extensions >= 0) { - (*blockp)[EDID_CHECKSUM_OFFSET] += (*blockp)[EDID_EXTENSION_FLAG_OFFSET] - valid_extensions; - (*blockp)[EDID_EXTENSION_FLAG_OFFSET] = valid_extensions; - new = krealloc(*blockp, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - } - if (!new) - kfree(*blockp); - - *blockp = new; + (*blockp)[EDID_CHECKSUM_OFFSET] += (*blockp)[EDID_EXTENSION_FLAG_OFFSET] - valid_extensions; + (*blockp)[EDID_EXTENSION_FLAG_OFFSET] = valid_extensions; } - return (new ? valid_extensions : -ENOMEM); } static bool @@ -506,8 +495,12 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) return block; new = krealloc(block, (block[EDID_EXTENSION_FLAG_OFFSET] + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto out; + if (!new) { + dev_warn(connector->dev->dev, "%s: cannot allocate memory for %d EDID blocks: trunkating.\n", + drm_get_connector_name(connector), block[EDID_EXTENSION_FLAG_OFFSET] + 1); + valid_extensions = 0; + goto no_more; + } block = new; for (j = 1; j <= block[EDID_EXTENSION_FLAG_OFFSET]; j++) { @@ -594,9 +587,8 @@ drm_validate_edid_blob(struct drm_connector *connector, u8 **blockp, int len) valid_extensions + 1, print_bad_edid)) valid_extensions++; } - ret = fixup_edid(blockp, valid_extensions); - } - if (ret < 0) + fixup_edid(blockp, valid_extensions); + } else connector->bad_edid_counter++; return ret; }