forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'drm-misc-next-fixes-2022-04-07' of git://anongit.freedeskt…
…op.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 <[email protected]> From: Maarten Lankhorst <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
- Loading branch information
Showing
10 changed files
with
540 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,261 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
/* | ||
* Copyright (C) 2022 Advanced Micro Devices, Inc. | ||
*/ | ||
|
||
#include <linux/dma-fence-unwrap.h> | ||
#if 0 | ||
#include <linux/kernel.h> | ||
#include <linux/kthread.h> | ||
#include <linux/mm.h> | ||
#include <linux/sched/signal.h> | ||
#include <linux/slab.h> | ||
#include <linux/spinlock.h> | ||
#include <linux/random.h> | ||
#endif | ||
|
||
#include "selftest.h" | ||
|
||
#define CHAIN_SZ (4 << 10) | ||
|
||
static inline struct mock_fence { | ||
struct dma_fence base; | ||
spinlock_t lock; | ||
} *to_mock_fence(struct dma_fence *f) { | ||
return container_of(f, struct mock_fence, base); | ||
} | ||
|
||
static const char *mock_name(struct dma_fence *f) | ||
{ | ||
return "mock"; | ||
} | ||
|
||
static const struct dma_fence_ops mock_ops = { | ||
.get_driver_name = mock_name, | ||
.get_timeline_name = mock_name, | ||
}; | ||
|
||
static struct dma_fence *mock_fence(void) | ||
{ | ||
struct mock_fence *f; | ||
|
||
f = kmalloc(sizeof(*f), GFP_KERNEL); | ||
if (!f) | ||
return NULL; | ||
|
||
spin_lock_init(&f->lock); | ||
dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0); | ||
|
||
return &f->base; | ||
} | ||
|
||
static struct dma_fence *mock_array(unsigned int num_fences, ...) | ||
{ | ||
struct dma_fence_array *array; | ||
struct dma_fence **fences; | ||
va_list valist; | ||
int i; | ||
|
||
fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); | ||
if (!fences) | ||
return NULL; | ||
|
||
va_start(valist, num_fences); | ||
for (i = 0; i < num_fences; ++i) | ||
fences[i] = va_arg(valist, typeof(*fences)); | ||
va_end(valist); | ||
|
||
array = dma_fence_array_create(num_fences, fences, | ||
dma_fence_context_alloc(1), | ||
1, false); | ||
if (!array) | ||
goto cleanup; | ||
return &array->base; | ||
|
||
cleanup: | ||
for (i = 0; i < num_fences; ++i) | ||
dma_fence_put(fences[i]); | ||
kfree(fences); | ||
return NULL; | ||
} | ||
|
||
static struct dma_fence *mock_chain(struct dma_fence *prev, | ||
struct dma_fence *fence) | ||
{ | ||
struct dma_fence_chain *f; | ||
|
||
f = dma_fence_chain_alloc(); | ||
if (!f) { | ||
dma_fence_put(prev); | ||
dma_fence_put(fence); | ||
return NULL; | ||
} | ||
|
||
dma_fence_chain_init(f, prev, fence, 1); | ||
return &f->base; | ||
} | ||
|
||
static int sanitycheck(void *arg) | ||
{ | ||
struct dma_fence *f, *chain, *array; | ||
int err = 0; | ||
|
||
f = mock_fence(); | ||
if (!f) | ||
return -ENOMEM; | ||
|
||
array = mock_array(1, f); | ||
if (!array) | ||
return -ENOMEM; | ||
|
||
chain = mock_chain(NULL, array); | ||
if (!chain) | ||
return -ENOMEM; | ||
|
||
dma_fence_signal(f); | ||
dma_fence_put(chain); | ||
return err; | ||
} | ||
|
||
static int unwrap_array(void *arg) | ||
{ | ||
struct dma_fence *fence, *f1, *f2, *array; | ||
struct dma_fence_unwrap iter; | ||
int err = 0; | ||
|
||
f1 = mock_fence(); | ||
if (!f1) | ||
return -ENOMEM; | ||
|
||
f2 = mock_fence(); | ||
if (!f2) { | ||
dma_fence_put(f1); | ||
return -ENOMEM; | ||
} | ||
|
||
array = mock_array(2, f1, f2); | ||
if (!array) | ||
return -ENOMEM; | ||
|
||
dma_fence_unwrap_for_each(fence, &iter, array) { | ||
if (fence == f1) { | ||
f1 = NULL; | ||
} else if (fence == f2) { | ||
f2 = NULL; | ||
} else { | ||
pr_err("Unexpected fence!\n"); | ||
err = -EINVAL; | ||
} | ||
} | ||
|
||
if (f1 || f2) { | ||
pr_err("Not all fences seen!\n"); | ||
err = -EINVAL; | ||
} | ||
|
||
dma_fence_signal(f1); | ||
dma_fence_signal(f2); | ||
dma_fence_put(array); | ||
return 0; | ||
} | ||
|
||
static int unwrap_chain(void *arg) | ||
{ | ||
struct dma_fence *fence, *f1, *f2, *chain; | ||
struct dma_fence_unwrap iter; | ||
int err = 0; | ||
|
||
f1 = mock_fence(); | ||
if (!f1) | ||
return -ENOMEM; | ||
|
||
f2 = mock_fence(); | ||
if (!f2) { | ||
dma_fence_put(f1); | ||
return -ENOMEM; | ||
} | ||
|
||
chain = mock_chain(f1, f2); | ||
if (!chain) | ||
return -ENOMEM; | ||
|
||
dma_fence_unwrap_for_each(fence, &iter, chain) { | ||
if (fence == f1) { | ||
f1 = NULL; | ||
} else if (fence == f2) { | ||
f2 = NULL; | ||
} else { | ||
pr_err("Unexpected fence!\n"); | ||
err = -EINVAL; | ||
} | ||
} | ||
|
||
if (f1 || f2) { | ||
pr_err("Not all fences seen!\n"); | ||
err = -EINVAL; | ||
} | ||
|
||
dma_fence_signal(f1); | ||
dma_fence_signal(f2); | ||
dma_fence_put(chain); | ||
return 0; | ||
} | ||
|
||
static int unwrap_chain_array(void *arg) | ||
{ | ||
struct dma_fence *fence, *f1, *f2, *array, *chain; | ||
struct dma_fence_unwrap iter; | ||
int err = 0; | ||
|
||
f1 = mock_fence(); | ||
if (!f1) | ||
return -ENOMEM; | ||
|
||
f2 = mock_fence(); | ||
if (!f2) { | ||
dma_fence_put(f1); | ||
return -ENOMEM; | ||
} | ||
|
||
array = mock_array(2, f1, f2); | ||
if (!array) | ||
return -ENOMEM; | ||
|
||
chain = mock_chain(NULL, array); | ||
if (!chain) | ||
return -ENOMEM; | ||
|
||
dma_fence_unwrap_for_each(fence, &iter, chain) { | ||
if (fence == f1) { | ||
f1 = NULL; | ||
} else if (fence == f2) { | ||
f2 = NULL; | ||
} else { | ||
pr_err("Unexpected fence!\n"); | ||
err = -EINVAL; | ||
} | ||
} | ||
|
||
if (f1 || f2) { | ||
pr_err("Not all fences seen!\n"); | ||
err = -EINVAL; | ||
} | ||
|
||
dma_fence_signal(f1); | ||
dma_fence_signal(f2); | ||
dma_fence_put(chain); | ||
return 0; | ||
} | ||
|
||
int dma_fence_unwrap(void) | ||
{ | ||
static const struct subtest tests[] = { | ||
SUBTEST(sanitycheck), | ||
SUBTEST(unwrap_array), | ||
SUBTEST(unwrap_chain), | ||
SUBTEST(unwrap_chain_array), | ||
}; | ||
|
||
return subtests(tests, NULL); | ||
} |
Oops, something went wrong.