From patchwork Tue Feb 26 11:19:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 10829919 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7CBF81515 for ; Tue, 26 Feb 2019 11:28:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6758A2B376 for ; Tue, 26 Feb 2019 11:28:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5BE6A2B397; Tue, 26 Feb 2019 11:28:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E1ADE2AA6F for ; Tue, 26 Feb 2019 11:28:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726018AbfBZL2O (ORCPT ); Tue, 26 Feb 2019 06:28:14 -0500 Received: from smtp02.tmcz.cz ([93.153.104.113]:52970 "EHLO smtp02.tmcz.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726004AbfBZL2O (ORCPT ); Tue, 26 Feb 2019 06:28:14 -0500 Received: from smtp02.tmcz.cz (localhost [127.0.0.1]) by sagator.hkvnode045 (Postfix) with ESMTP id 164BB94B39F; Tue, 26 Feb 2019 12:21:33 +0100 (CET) X-Sagator-Scanner: 1.3.1-1 at hkvnode046; log(status(custom_action(quarantine(clamd()))), status(custom_action(quarantine(SpamAssassinD())))) X-Sagator-ID: 20190226-122133-0001-02447-Wx30hI@hkvnode046 Received: from leontynka.twibright.com (unknown [109.183.129.149]) by smtp02.tmcz.cz (Postfix) with ESMTPS; Tue, 26 Feb 2019 12:21:33 +0100 (CET) Received: from root by leontynka.twibright.com with local (Exim 4.89) (envelope-from ) id 1gyana-0002qh-KX; Tue, 26 Feb 2019 12:21:22 +0100 Message-Id: <20190226112122.413085116@twibright.com> User-Agent: quilt/0.63-1 Date: Tue, 26 Feb 2019 12:19:47 +0100 From: Mikulas Patocka To: Mikulas Patocka , Bernie Thompson , Bartlomiej Zolnierkiewicz , Ladislav Michl Cc: linux-fbdev@vger.kernel.org Subject: [PATCH 3/3] dlfb: introduce a rendering mutex References: <20190226111944.505404435@twibright.com> MIME-Version: 1.0 Content-Disposition: inline; filename=dlfb-rendering-mutex.patch Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Rendering calls may be done simultaneously from the workqueue, dlfb_ops_write, dlfb_ops_ioctl, dlfb_ops_set_par and dlfb_dpy_deferred_io. The code is robust enough so that it won't crash on concurrent rendering. However, concurrent rendering may cause display corruption if the same pixel is simultaneously being rendered. In order to avoid this corruption, this patch adds a mutex around the rendering calls. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org --- drivers/video/fbdev/udlfb.c | 41 ++++++++++++++++++++++++++++++----------- include/video/udlfb.h | 1 + 2 files changed, 31 insertions(+), 11 deletions(-) Index: linux-4.19.25/drivers/video/fbdev/udlfb.c =================================================================== --- linux-4.19.25.orig/drivers/video/fbdev/udlfb.c 2019-02-25 16:24:05.000000000 +0100 +++ linux-4.19.25/drivers/video/fbdev/udlfb.c 2019-02-25 16:27:35.000000000 +0100 @@ -596,7 +596,7 @@ static int dlfb_render_hline(struct dlfb static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) { - int i; + int i, ret; char *cmd; cycles_t start_cycles, end_cycles; int bytes_sent = 0; @@ -606,21 +606,29 @@ static int dlfb_handle_damage(struct dlf start_cycles = get_cycles(); + mutex_lock(&dlfb->render_mutex); + aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); x = aligned_x; if ((width <= 0) || (x + width > dlfb->info->var.xres) || - (y + height > dlfb->info->var.yres)) - return -EINVAL; + (y + height > dlfb->info->var.yres)) { + ret = -EINVAL; + goto unlock_ret; + } - if (!atomic_read(&dlfb->usb_active)) - return 0; + if (!atomic_read(&dlfb->usb_active)) { + ret = 0; + goto unlock_ret; + } urb = dlfb_get_urb(dlfb); - if (!urb) - return 0; + if (!urb) { + ret = 0; + goto unlock_ret; + } cmd = urb->transfer_buffer; for (i = y; i < y + height ; i++) { @@ -654,7 +662,11 @@ error: >> 10)), /* Kcycles */ &dlfb->cpu_kcycles_used); - return 0; + ret = 0; + +unlock_ret: + mutex_unlock(&dlfb->render_mutex); + return ret; } static void dlfb_init_damage(struct dlfb_data *dlfb) @@ -782,17 +794,19 @@ static void dlfb_dpy_deferred_io(struct int bytes_identical = 0; int bytes_rendered = 0; + mutex_lock(&dlfb->render_mutex); + if (!fb_defio) - return; + goto unlock_ret; if (!atomic_read(&dlfb->usb_active)) - return; + goto unlock_ret; start_cycles = get_cycles(); urb = dlfb_get_urb(dlfb); if (!urb) - return; + goto unlock_ret; cmd = urb->transfer_buffer; @@ -825,6 +839,8 @@ error: atomic_add(((unsigned int) ((end_cycles - start_cycles) >> 10)), /* Kcycles */ &dlfb->cpu_kcycles_used); +unlock_ret: + mutex_unlock(&dlfb->render_mutex); } static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len) @@ -986,6 +1002,8 @@ static void dlfb_ops_destroy(struct fb_i cancel_work_sync(&dlfb->damage_work); + mutex_destroy(&dlfb->render_mutex); + if (info->cmap.len != 0) fb_dealloc_cmap(&info->cmap); if (info->monspecs.modedb) @@ -1682,6 +1700,7 @@ static int dlfb_usb_probe(struct usb_int dlfb->ops = dlfb_ops; info->fbops = &dlfb->ops; + mutex_init(&dlfb->render_mutex); dlfb_init_damage(dlfb); spin_lock_init(&dlfb->damage_lock); INIT_WORK(&dlfb->damage_work, dlfb_damage_work); Index: linux-4.19.25/include/video/udlfb.h =================================================================== --- linux-4.19.25.orig/include/video/udlfb.h 2019-02-25 16:24:05.000000000 +0100 +++ linux-4.19.25/include/video/udlfb.h 2019-02-25 16:24:05.000000000 +0100 @@ -48,6 +48,7 @@ struct dlfb_data { int base8; u32 pseudo_palette[256]; int blank_mode; /*one of FB_BLANK_ */ + struct mutex render_mutex; int damage_x; int damage_y; int damage_x2;