]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/udlfb-introduce-a-rendering-mutex.patch
7d1a891e8495b2e8207d845c54ecd352f8352e82
[thirdparty/kernel/stable-queue.git] / queue-4.19 / udlfb-introduce-a-rendering-mutex.patch
1 From babc250e278eac7b0e671bdaedf833759b43bb78 Mon Sep 17 00:00:00 2001
2 From: Mikulas Patocka <mpatocka@redhat.com>
3 Date: Mon, 1 Apr 2019 17:46:57 +0200
4 Subject: udlfb: introduce a rendering mutex
5
6 From: Mikulas Patocka <mpatocka@redhat.com>
7
8 commit babc250e278eac7b0e671bdaedf833759b43bb78 upstream.
9
10 Rendering calls may be done simultaneously from the workqueue,
11 dlfb_ops_write, dlfb_ops_ioctl, dlfb_ops_set_par and dlfb_dpy_deferred_io.
12 The code is robust enough so that it won't crash on concurrent rendering.
13
14 However, concurrent rendering may cause display corruption if the same
15 pixel is simultaneously being rendered. In order to avoid this corruption,
16 this patch adds a mutex around the rendering calls.
17
18 Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
19 Cc: Bernie Thompson <bernie@plugable.com>
20 Cc: Ladislav Michl <ladis@linux-mips.org>
21 Cc: <stable@vger.kernel.org>
22 [b.zolnierkie: replace "dlfb:" with "uldfb:" in the patch summary]
23 Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25
26 ---
27 drivers/video/fbdev/udlfb.c | 41 ++++++++++++++++++++++++++++++-----------
28 include/video/udlfb.h | 1 +
29 2 files changed, 31 insertions(+), 11 deletions(-)
30
31 --- a/drivers/video/fbdev/udlfb.c
32 +++ b/drivers/video/fbdev/udlfb.c
33 @@ -596,7 +596,7 @@ static int dlfb_render_hline(struct dlfb
34
35 static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height)
36 {
37 - int i;
38 + int i, ret;
39 char *cmd;
40 cycles_t start_cycles, end_cycles;
41 int bytes_sent = 0;
42 @@ -606,21 +606,29 @@ static int dlfb_handle_damage(struct dlf
43
44 start_cycles = get_cycles();
45
46 + mutex_lock(&dlfb->render_mutex);
47 +
48 aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
49 width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
50 x = aligned_x;
51
52 if ((width <= 0) ||
53 (x + width > dlfb->info->var.xres) ||
54 - (y + height > dlfb->info->var.yres))
55 - return -EINVAL;
56 + (y + height > dlfb->info->var.yres)) {
57 + ret = -EINVAL;
58 + goto unlock_ret;
59 + }
60
61 - if (!atomic_read(&dlfb->usb_active))
62 - return 0;
63 + if (!atomic_read(&dlfb->usb_active)) {
64 + ret = 0;
65 + goto unlock_ret;
66 + }
67
68 urb = dlfb_get_urb(dlfb);
69 - if (!urb)
70 - return 0;
71 + if (!urb) {
72 + ret = 0;
73 + goto unlock_ret;
74 + }
75 cmd = urb->transfer_buffer;
76
77 for (i = y; i < y + height ; i++) {
78 @@ -654,7 +662,11 @@ error:
79 >> 10)), /* Kcycles */
80 &dlfb->cpu_kcycles_used);
81
82 - return 0;
83 + ret = 0;
84 +
85 +unlock_ret:
86 + mutex_unlock(&dlfb->render_mutex);
87 + return ret;
88 }
89
90 static void dlfb_init_damage(struct dlfb_data *dlfb)
91 @@ -782,17 +794,19 @@ static void dlfb_dpy_deferred_io(struct
92 int bytes_identical = 0;
93 int bytes_rendered = 0;
94
95 + mutex_lock(&dlfb->render_mutex);
96 +
97 if (!fb_defio)
98 - return;
99 + goto unlock_ret;
100
101 if (!atomic_read(&dlfb->usb_active))
102 - return;
103 + goto unlock_ret;
104
105 start_cycles = get_cycles();
106
107 urb = dlfb_get_urb(dlfb);
108 if (!urb)
109 - return;
110 + goto unlock_ret;
111
112 cmd = urb->transfer_buffer;
113
114 @@ -825,6 +839,8 @@ error:
115 atomic_add(((unsigned int) ((end_cycles - start_cycles)
116 >> 10)), /* Kcycles */
117 &dlfb->cpu_kcycles_used);
118 +unlock_ret:
119 + mutex_unlock(&dlfb->render_mutex);
120 }
121
122 static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
123 @@ -986,6 +1002,8 @@ static void dlfb_ops_destroy(struct fb_i
124
125 cancel_work_sync(&dlfb->damage_work);
126
127 + mutex_destroy(&dlfb->render_mutex);
128 +
129 if (info->cmap.len != 0)
130 fb_dealloc_cmap(&info->cmap);
131 if (info->monspecs.modedb)
132 @@ -1682,6 +1700,7 @@ static int dlfb_usb_probe(struct usb_int
133 dlfb->ops = dlfb_ops;
134 info->fbops = &dlfb->ops;
135
136 + mutex_init(&dlfb->render_mutex);
137 dlfb_init_damage(dlfb);
138 spin_lock_init(&dlfb->damage_lock);
139 INIT_WORK(&dlfb->damage_work, dlfb_damage_work);
140 --- a/include/video/udlfb.h
141 +++ b/include/video/udlfb.h
142 @@ -48,6 +48,7 @@ struct dlfb_data {
143 int base8;
144 u32 pseudo_palette[256];
145 int blank_mode; /*one of FB_BLANK_ */
146 + struct mutex render_mutex;
147 int damage_x;
148 int damage_y;
149 int damage_x2;