Skip to content

Commit 995f748

Browse files
committed
Merge tag 'drm-misc-next-fixes-2022-04-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
drm-misc-next-fixes for v5.18-rc2: - fix warning about fence containers - fix logic error in new fence merge code - handle empty dma_fence_arrays gracefully - Try all possible cases for bridge/panel detection. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/3b8e6439-612e-f640-e380-51e834393e94@linux.intel.com
2 parents dc7d19d + 67bae5f commit 995f748

10 files changed

Lines changed: 540 additions & 117 deletions

File tree

Documentation/driver-api/dma-buf.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ DMA Fence Chain
185185
.. kernel-doc:: include/linux/dma-fence-chain.h
186186
:internal:
187187

188+
DMA Fence unwrap
189+
~~~~~~~~~~~~~~~~
190+
191+
.. kernel-doc:: include/linux/dma-fence-unwrap.h
192+
:internal:
193+
188194
DMA Fence uABI/Sync File
189195
~~~~~~~~~~~~~~~~~~~~~~~~
190196

drivers/dma-buf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dmabuf_selftests-y := \
1212
selftest.o \
1313
st-dma-fence.o \
1414
st-dma-fence-chain.o \
15+
st-dma-fence-unwrap.o \
1516
st-dma-resv.o
1617

1718
obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o

drivers/dma-buf/dma-fence-array.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ struct dma_fence_array *dma_fence_array_create(int num_fences,
159159
struct dma_fence_array *array;
160160
size_t size = sizeof(*array);
161161

162+
WARN_ON(!num_fences || !fences);
163+
162164
/* Allocate the callback structures behind the array. */
163165
size += num_fences * sizeof(struct dma_fence_array_cb);
164166
array = kzalloc(size, GFP_KERNEL);
@@ -219,3 +221,33 @@ bool dma_fence_match_context(struct dma_fence *fence, u64 context)
219221
return true;
220222
}
221223
EXPORT_SYMBOL(dma_fence_match_context);
224+
225+
struct dma_fence *dma_fence_array_first(struct dma_fence *head)
226+
{
227+
struct dma_fence_array *array;
228+
229+
if (!head)
230+
return NULL;
231+
232+
array = to_dma_fence_array(head);
233+
if (!array)
234+
return head;
235+
236+
if (!array->num_fences)
237+
return NULL;
238+
239+
return array->fences[0];
240+
}
241+
EXPORT_SYMBOL(dma_fence_array_first);
242+
243+
struct dma_fence *dma_fence_array_next(struct dma_fence *head,
244+
unsigned int index)
245+
{
246+
struct dma_fence_array *array = to_dma_fence_array(head);
247+
248+
if (!array || index >= array->num_fences)
249+
return NULL;
250+
251+
return array->fences[index];
252+
}
253+
EXPORT_SYMBOL(dma_fence_array_next);

drivers/dma-buf/selftests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */
1313
selftest(dma_fence, dma_fence)
1414
selftest(dma_fence_chain, dma_fence_chain)
15+
selftest(dma_fence_unwrap, dma_fence_unwrap)
1516
selftest(dma_resv, dma_resv)
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
/*
4+
* Copyright (C) 2022 Advanced Micro Devices, Inc.
5+
*/
6+
7+
#include <linux/dma-fence-unwrap.h>
8+
#if 0
9+
#include <linux/kernel.h>
10+
#include <linux/kthread.h>
11+
#include <linux/mm.h>
12+
#include <linux/sched/signal.h>
13+
#include <linux/slab.h>
14+
#include <linux/spinlock.h>
15+
#include <linux/random.h>
16+
#endif
17+
18+
#include "selftest.h"
19+
20+
#define CHAIN_SZ (4 << 10)
21+
22+
static inline struct mock_fence {
23+
struct dma_fence base;
24+
spinlock_t lock;
25+
} *to_mock_fence(struct dma_fence *f) {
26+
return container_of(f, struct mock_fence, base);
27+
}
28+
29+
static const char *mock_name(struct dma_fence *f)
30+
{
31+
return "mock";
32+
}
33+
34+
static const struct dma_fence_ops mock_ops = {
35+
.get_driver_name = mock_name,
36+
.get_timeline_name = mock_name,
37+
};
38+
39+
static struct dma_fence *mock_fence(void)
40+
{
41+
struct mock_fence *f;
42+
43+
f = kmalloc(sizeof(*f), GFP_KERNEL);
44+
if (!f)
45+
return NULL;
46+
47+
spin_lock_init(&f->lock);
48+
dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
49+
50+
return &f->base;
51+
}
52+
53+
static struct dma_fence *mock_array(unsigned int num_fences, ...)
54+
{
55+
struct dma_fence_array *array;
56+
struct dma_fence **fences;
57+
va_list valist;
58+
int i;
59+
60+
fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
61+
if (!fences)
62+
return NULL;
63+
64+
va_start(valist, num_fences);
65+
for (i = 0; i < num_fences; ++i)
66+
fences[i] = va_arg(valist, typeof(*fences));
67+
va_end(valist);
68+
69+
array = dma_fence_array_create(num_fences, fences,
70+
dma_fence_context_alloc(1),
71+
1, false);
72+
if (!array)
73+
goto cleanup;
74+
return &array->base;
75+
76+
cleanup:
77+
for (i = 0; i < num_fences; ++i)
78+
dma_fence_put(fences[i]);
79+
kfree(fences);
80+
return NULL;
81+
}
82+
83+
static struct dma_fence *mock_chain(struct dma_fence *prev,
84+
struct dma_fence *fence)
85+
{
86+
struct dma_fence_chain *f;
87+
88+
f = dma_fence_chain_alloc();
89+
if (!f) {
90+
dma_fence_put(prev);
91+
dma_fence_put(fence);
92+
return NULL;
93+
}
94+
95+
dma_fence_chain_init(f, prev, fence, 1);
96+
return &f->base;
97+
}
98+
99+
static int sanitycheck(void *arg)
100+
{
101+
struct dma_fence *f, *chain, *array;
102+
int err = 0;
103+
104+
f = mock_fence();
105+
if (!f)
106+
return -ENOMEM;
107+
108+
array = mock_array(1, f);
109+
if (!array)
110+
return -ENOMEM;
111+
112+
chain = mock_chain(NULL, array);
113+
if (!chain)
114+
return -ENOMEM;
115+
116+
dma_fence_signal(f);
117+
dma_fence_put(chain);
118+
return err;
119+
}
120+
121+
static int unwrap_array(void *arg)
122+
{
123+
struct dma_fence *fence, *f1, *f2, *array;
124+
struct dma_fence_unwrap iter;
125+
int err = 0;
126+
127+
f1 = mock_fence();
128+
if (!f1)
129+
return -ENOMEM;
130+
131+
f2 = mock_fence();
132+
if (!f2) {
133+
dma_fence_put(f1);
134+
return -ENOMEM;
135+
}
136+
137+
array = mock_array(2, f1, f2);
138+
if (!array)
139+
return -ENOMEM;
140+
141+
dma_fence_unwrap_for_each(fence, &iter, array) {
142+
if (fence == f1) {
143+
f1 = NULL;
144+
} else if (fence == f2) {
145+
f2 = NULL;
146+
} else {
147+
pr_err("Unexpected fence!\n");
148+
err = -EINVAL;
149+
}
150+
}
151+
152+
if (f1 || f2) {
153+
pr_err("Not all fences seen!\n");
154+
err = -EINVAL;
155+
}
156+
157+
dma_fence_signal(f1);
158+
dma_fence_signal(f2);
159+
dma_fence_put(array);
160+
return 0;
161+
}
162+
163+
static int unwrap_chain(void *arg)
164+
{
165+
struct dma_fence *fence, *f1, *f2, *chain;
166+
struct dma_fence_unwrap iter;
167+
int err = 0;
168+
169+
f1 = mock_fence();
170+
if (!f1)
171+
return -ENOMEM;
172+
173+
f2 = mock_fence();
174+
if (!f2) {
175+
dma_fence_put(f1);
176+
return -ENOMEM;
177+
}
178+
179+
chain = mock_chain(f1, f2);
180+
if (!chain)
181+
return -ENOMEM;
182+
183+
dma_fence_unwrap_for_each(fence, &iter, chain) {
184+
if (fence == f1) {
185+
f1 = NULL;
186+
} else if (fence == f2) {
187+
f2 = NULL;
188+
} else {
189+
pr_err("Unexpected fence!\n");
190+
err = -EINVAL;
191+
}
192+
}
193+
194+
if (f1 || f2) {
195+
pr_err("Not all fences seen!\n");
196+
err = -EINVAL;
197+
}
198+
199+
dma_fence_signal(f1);
200+
dma_fence_signal(f2);
201+
dma_fence_put(chain);
202+
return 0;
203+
}
204+
205+
static int unwrap_chain_array(void *arg)
206+
{
207+
struct dma_fence *fence, *f1, *f2, *array, *chain;
208+
struct dma_fence_unwrap iter;
209+
int err = 0;
210+
211+
f1 = mock_fence();
212+
if (!f1)
213+
return -ENOMEM;
214+
215+
f2 = mock_fence();
216+
if (!f2) {
217+
dma_fence_put(f1);
218+
return -ENOMEM;
219+
}
220+
221+
array = mock_array(2, f1, f2);
222+
if (!array)
223+
return -ENOMEM;
224+
225+
chain = mock_chain(NULL, array);
226+
if (!chain)
227+
return -ENOMEM;
228+
229+
dma_fence_unwrap_for_each(fence, &iter, chain) {
230+
if (fence == f1) {
231+
f1 = NULL;
232+
} else if (fence == f2) {
233+
f2 = NULL;
234+
} else {
235+
pr_err("Unexpected fence!\n");
236+
err = -EINVAL;
237+
}
238+
}
239+
240+
if (f1 || f2) {
241+
pr_err("Not all fences seen!\n");
242+
err = -EINVAL;
243+
}
244+
245+
dma_fence_signal(f1);
246+
dma_fence_signal(f2);
247+
dma_fence_put(chain);
248+
return 0;
249+
}
250+
251+
int dma_fence_unwrap(void)
252+
{
253+
static const struct subtest tests[] = {
254+
SUBTEST(sanitycheck),
255+
SUBTEST(unwrap_array),
256+
SUBTEST(unwrap_chain),
257+
SUBTEST(unwrap_chain_array),
258+
};
259+
260+
return subtests(tests, NULL);
261+
}

0 commit comments

Comments
 (0)