From patchwork Tue Feb 26 11:19:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 10829921 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 96E72180E 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 841E32AA6F for ; Tue, 26 Feb 2019 11:28:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 738222B3F4; 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 103FC2B332 for ; Tue, 26 Feb 2019 11:28:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726004AbfBZL2O (ORCPT ); Tue, 26 Feb 2019 06:28:14 -0500 Received: from smtp02.tmcz.cz ([93.153.104.113]:52974 "EHLO smtp02.tmcz.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725935AbfBZL2O (ORCPT ); Tue, 26 Feb 2019 06:28:14 -0500 X-Greylist: delayed 395 seconds by postgrey-1.27 at vger.kernel.org; Tue, 26 Feb 2019 06:28:11 EST Received: from smtp02.tmcz.cz (localhost [127.0.0.1]) by sagator.hkvnode045 (Postfix) with ESMTP id AFF9694BB0B; Tue, 26 Feb 2019 12:21:32 +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-122132-0001-02206-eEZtDh@hkvnode046 Received: from leontynka.twibright.com (unknown [109.183.129.149]) by smtp02.tmcz.cz (Postfix) with ESMTPS; Tue, 26 Feb 2019 12:21:32 +0100 (CET) Received: from root by leontynka.twibright.com with local (Exim 4.89) (envelope-from ) id 1gyana-0002pZ-4a; Tue, 26 Feb 2019 12:21:22 +0100 Message-Id: <20190226112121.910471265@twibright.com> User-Agent: quilt/0.63-1 Date: Tue, 26 Feb 2019 12:19:45 +0100 From: Mikulas Patocka To: Mikulas Patocka , Bernie Thompson , Bartlomiej Zolnierkiewicz , Ladislav Michl Cc: linux-fbdev@vger.kernel.org Subject: [PATCH 1/3] udlfb: delete the unused parameter for dlfb_handle_damage References: <20190226111944.505404435@twibright.com> MIME-Version: 1.0 Content-Disposition: inline; filename=dlfb-remove-unused-variables.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 Remove the unused parameter "data" and unused variable "ret". Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org --- drivers/video/fbdev/udlfb.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) Index: linux-4.19.25/drivers/video/fbdev/udlfb.c =================================================================== --- linux-4.19.25.orig/drivers/video/fbdev/udlfb.c 2019-02-25 15:42:57.000000000 +0100 +++ linux-4.19.25/drivers/video/fbdev/udlfb.c 2019-02-25 15:43:16.000000000 +0100 @@ -594,10 +594,9 @@ static int dlfb_render_hline(struct dlfb return 0; } -static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, - int width, int height, char *data) +static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) { - int i, ret; + int i; char *cmd; cycles_t start_cycles, end_cycles; int bytes_sent = 0; @@ -641,7 +640,7 @@ static int dlfb_handle_damage(struct dlf *cmd++ = 0xAF; /* Send partial buffer remaining before exiting */ len = cmd - (char *) urb->transfer_buffer; - ret = dlfb_submit_urb(dlfb, urb, len); + dlfb_submit_urb(dlfb, urb, len); bytes_sent += len; } else dlfb_urb_completion(urb); @@ -679,7 +678,7 @@ static ssize_t dlfb_ops_write(struct fb_ (u32)info->var.yres); dlfb_handle_damage(dlfb, 0, start, info->var.xres, - lines, info->screen_base); + lines); } return result; @@ -695,7 +694,7 @@ static void dlfb_ops_copyarea(struct fb_ sys_copyarea(info, area); dlfb_handle_damage(dlfb, area->dx, area->dy, - area->width, area->height, info->screen_base); + area->width, area->height); } static void dlfb_ops_imageblit(struct fb_info *info, @@ -706,7 +705,7 @@ static void dlfb_ops_imageblit(struct fb sys_imageblit(info, image); dlfb_handle_damage(dlfb, image->dx, image->dy, - image->width, image->height, info->screen_base); + image->width, image->height); } static void dlfb_ops_fillrect(struct fb_info *info, @@ -717,7 +716,7 @@ static void dlfb_ops_fillrect(struct fb_ sys_fillrect(info, rect); dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width, - rect->height, info->screen_base); + rect->height); } /* @@ -859,8 +858,7 @@ static int dlfb_ops_ioctl(struct fb_info if (area.y > info->var.yres) area.y = info->var.yres; - dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h, - info->screen_base); + dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h); } return 0; @@ -1065,8 +1063,7 @@ static int dlfb_ops_set_par(struct fb_in pix_framebuffer[i] = 0x37e6; } - dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres, - info->screen_base); + dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres); return 0; } From patchwork Tue Feb 26 11:19:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 10829925 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 2DC7F1575 for ; Tue, 26 Feb 2019 11:29:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A2BF2A6B3 for ; Tue, 26 Feb 2019 11:29:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0DBD52A7BF; Tue, 26 Feb 2019 11:29:57 +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 94FE02A6B3 for ; Tue, 26 Feb 2019 11:29:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725935AbfBZL34 (ORCPT ); Tue, 26 Feb 2019 06:29:56 -0500 Received: from smtp01.tmcz.cz ([93.153.104.112]:39968 "EHLO smtp01.tmcz.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726283AbfBZL34 (ORCPT ); Tue, 26 Feb 2019 06:29:56 -0500 Received: from smtp01.tmcz.cz (localhost [127.0.0.1]) by sagator.hkvnode045 (Postfix) with ESMTP id C9335949FBC; Tue, 26 Feb 2019 12:21:32 +0100 (CET) X-Sagator-Scanner: 1.3.1-1 at hkvnode045; log(status(custom_action(quarantine(clamd()))), status(custom_action(quarantine(SpamAssassinD())))) X-Sagator-ID: 20190226-122132-0001-02459-EbplNO@hkvnode045 Received: from leontynka.twibright.com (unknown [109.183.129.149]) by smtp01.tmcz.cz (Postfix) with ESMTPS; Tue, 26 Feb 2019 12:21:32 +0100 (CET) Received: from root by leontynka.twibright.com with local (Exim 4.89) (envelope-from ) id 1gyana-0002q5-Cc; Tue, 26 Feb 2019 12:21:22 +0100 Message-Id: <20190226112122.160829572@twibright.com> User-Agent: quilt/0.63-1 Date: Tue, 26 Feb 2019 12:19:46 +0100 From: Mikulas Patocka To: Mikulas Patocka , Bernie Thompson , Bartlomiej Zolnierkiewicz , Ladislav Michl Cc: linux-fbdev@vger.kernel.org Subject: [PATCH 2/3] udlfb: fix sleeping inside spinlock References: <20190226111944.505404435@twibright.com> MIME-Version: 1.0 Content-Disposition: inline; filename=dlfb-offload-damage.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 If a framebuffer device is used as a console, the rendering calls (copyarea, fillrect, imageblit) may be done with the console spinlock held. On udlfb, these function call dlfb_handle_damage that takes a blocking semaphore before acquiring an URB. In order to fix the bug, this patch changes the calls copyarea, fillrect and imageblit to offload USB work to a workqueue. A side effect of this patch is 3x improvement in console scrolling speed because the device doesn't have to be updated after each copyarea call. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org --- drivers/video/fbdev/udlfb.c | 56 +++++++++++++++++++++++++++++++++++++++++--- include/video/udlfb.h | 6 ++++ 2 files changed, 59 insertions(+), 3 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:19:19.000000000 +0100 +++ linux-4.19.25/drivers/video/fbdev/udlfb.c 2019-02-25 16:23:05.000000000 +0100 @@ -657,6 +657,50 @@ error: return 0; } +static void dlfb_init_damage(struct dlfb_data *dlfb) +{ + dlfb->damage_x = INT_MAX; + dlfb->damage_x2 = 0; + dlfb->damage_y = INT_MAX; + dlfb->damage_y2 = 0; +} + +static void dlfb_damage_work(struct work_struct *w) +{ + struct dlfb_data *dlfb = container_of(w, struct dlfb_data, damage_work); + int x, x2, y, y2; + + spin_lock_irq(&dlfb->damage_lock); + x = dlfb->damage_x; + x2 = dlfb->damage_x2; + y = dlfb->damage_y; + y2 = dlfb->damage_y2; + dlfb_init_damage(dlfb); + spin_unlock_irq(&dlfb->damage_lock); + + if (x < x2 && y < y2) + dlfb_handle_damage(dlfb, x, y, x2 - x, y2 - y); +} + +static void dlfb_offload_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) +{ + unsigned long flags; + int x2 = x + width; + int y2 = y + height; + + if (x >= x2 || y >= y2) + return; + + spin_lock_irqsave(&dlfb->damage_lock, flags); + dlfb->damage_x = min(x, dlfb->damage_x); + dlfb->damage_x2 = max(x2, dlfb->damage_x2); + dlfb->damage_y = min(y, dlfb->damage_y); + dlfb->damage_y2 = max(y2, dlfb->damage_y2); + spin_unlock_irqrestore(&dlfb->damage_lock, flags); + + schedule_work(&dlfb->damage_work); +} + /* * Path triggered by usermode clients who write to filesystem * e.g. cat filename > /dev/fb1 @@ -693,7 +737,7 @@ static void dlfb_ops_copyarea(struct fb_ sys_copyarea(info, area); - dlfb_handle_damage(dlfb, area->dx, area->dy, + dlfb_offload_damage(dlfb, area->dx, area->dy, area->width, area->height); } @@ -704,7 +748,7 @@ static void dlfb_ops_imageblit(struct fb sys_imageblit(info, image); - dlfb_handle_damage(dlfb, image->dx, image->dy, + dlfb_offload_damage(dlfb, image->dx, image->dy, image->width, image->height); } @@ -715,7 +759,7 @@ static void dlfb_ops_fillrect(struct fb_ sys_fillrect(info, rect); - dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width, + dlfb_offload_damage(dlfb, rect->dx, rect->dy, rect->width, rect->height); } @@ -940,6 +984,8 @@ static void dlfb_ops_destroy(struct fb_i { struct dlfb_data *dlfb = info->par; + cancel_work_sync(&dlfb->damage_work); + if (info->cmap.len != 0) fb_dealloc_cmap(&info->cmap); if (info->monspecs.modedb) @@ -1636,6 +1682,10 @@ static int dlfb_usb_probe(struct usb_int dlfb->ops = dlfb_ops; info->fbops = &dlfb->ops; + dlfb_init_damage(dlfb); + spin_lock_init(&dlfb->damage_lock); + INIT_WORK(&dlfb->damage_work, dlfb_damage_work); + INIT_LIST_HEAD(&info->modelist); if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { Index: linux-4.19.25/include/video/udlfb.h =================================================================== --- linux-4.19.25.orig/include/video/udlfb.h 2019-02-25 16:19:19.000000000 +0100 +++ linux-4.19.25/include/video/udlfb.h 2019-02-25 16:19:19.000000000 +0100 @@ -48,6 +48,12 @@ struct dlfb_data { int base8; u32 pseudo_palette[256]; int blank_mode; /*one of FB_BLANK_ */ + int damage_x; + int damage_y; + int damage_x2; + int damage_y2; + spinlock_t damage_lock; + struct work_struct damage_work; struct fb_ops ops; /* blit-only rendering path metrics, exposed through sysfs */ atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ 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;