From: Benjamin Gaignard <benjamin.gaignard(a)linaro.org>
The goal of this serie of patches is to add a way to use
dmabuf file descriptor inside wayland and weston.
In a context where there is no Mesa EGL (and so no wl_drm protocol) wl_dmabuf
could be used as an alternative to shm to share buffers between hardware
devices. If your hardware device (video decoder, renderer, etc...) need
physical contiguous memory (obviously don't have MMU) wl_dmabuf may save
the cost of one copy compare to shm.
shm case:
videodecoder --(copy into shm_buffer)--> weston(+pixman) --> HW renderer
dmabuf case:
videodecoder --(directly write in dmabuf buffer)--> weston(+pixman) --> HW renderer
The server is responsible to send its supported pixel formats and the device
name to be used by the client to allocate buffers.
While mmap() call on dmabuf file descriptor result isn't guaranty on all
architectures both server and client should take care of it before accessing
to buffer data to avoid segfault.
=== Wayland ===
Benjamin Gaignard (1):
Add wl_dmabuf protocol
protocol/Makefile.am | 6 +-
protocol/wayland-dmabuf.xml | 133 +++++++++++++++++++++
src/Makefile.am | 12 +-
src/wayland-dmabuf.c | 279 +++++++++++++++++++++++++++++++++++++++++++
src/wayland-dmabuf.h | 136 +++++++++++++++++++++
5 files changed, 562 insertions(+), 4 deletions(-)
create mode 100644 protocol/wayland-dmabuf.xml
create mode 100644 src/wayland-dmabuf.c
create mode 100644 src/wayland-dmabuf.h
=== Weston ===
Benjamin Gaignard (1):
compositor-drm: allow to be a wl_dmabuf server
src/compositor-drm.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++--
src/compositor.c | 4 +-
src/compositor.h | 2 +
src/pixman-renderer.c | 86 ++++++++++++++++++-------
4 files changed, 230 insertions(+), 30 deletions(-)
--
1.7.9.5
Hi all,
I'm working for Linaro on enabling a zero copy path in GStreamer by
using dmabuf.
To make this possible I have patched gst wayland sink to use wayland
drm protocol: https://bugzilla.gnome.org/show_bug.cgi?id=711155
Today wayland drm protocol is limited to Mesa so I have decided to
move it into wayland-core.
My hardware doesn't have gpu support yet so I have patched weston
(pixman) to allow usage of wl_drm buffers.
With this I able to share/use a buffer allocated by DRM in gstreamer
pipeline even if I don't have gpu and EGL.
What do you think about make wayland drm protocol available like this ?
Please note those patches are for wayland/weston 1.1.0
Regards,
Benjamin
--
Benjamin Gaignard
Graphic Working Group
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
On Fri, Nov 22, 2013 at 12:01 PM, Keith Packard <keithp(a)keithp.com> wrote:
> Daniel Vetter <daniel(a)ffwll.ch> writes:
>
>> Hm, where do we have the canonical source for all these fourcc codes? I'm
>> asking since we have our own copy in the kernel as drm_fourcc.h, and that
>> one is part of the userspace ABI since we use it to pass around
>> framebuffer formats and format lists.
>
> I think it's the kernel? I really don't know, as the whole notion of
> fourcc codes seems crazy to me...
>
> Feel free to steal this code and stick it in the kernel if you like.
Well, I wasn't ever in favour of using fourcc codes since they're just
not standardized at all, highly redundant in some cases and also miss
lots of stuff we actually need (like all the rgb formats).
Cc'ing the heck out of this to get kernel people to hopefully notice.
Maybe someone takes charge of this ... Otherwise meh.
>> Just afraid to create long-term maintainance madness here with the
>> kernel's iron thou-shalt-not-break-userspace-ever rule ... Not likely
>> we'll ever accept srgb for framebuffers though.
>
> Would suck to collide with something we do want though.
Yeah, it'd suck. But given how fourcc works we probably have that
already, just haven't noticed yet :(
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
Hi all!
Benjamin Herrenschmidt pointed a few issues in the proposed design of
device tree bindings for contiguous memory allocator and reserved memory
regions:
https://lkml.org/lkml/2013/9/15/151http://www.spinics.net/lists/arm-kernel/msg273548.html
Some time has passed, but there is still no consensus on the bindings
for the reserved memory and various drawback of this solution has been
shown, so in my opinion the best I can do now is to revert them
completely and start from scratch again later.
This patch series reverts patches related to device tree bindings
proposed in the following thread:
http://thread.gmane.org/gmane.linux.ports.arm.kernel/263216
and merged by commit 64c353864e3f7ccba0ade1bd6f562f9a3bc7e68d ("Merge
branch 'for-v3.12' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping").
Best regards
Marek Szyprowski
Samsung R&D Institute Poland
Marek Szyprowski (2):
Revert "ARM: init: add support for reserved memory defined by device tree"
Revert "drivers: of: add initialization code for dma reserved memory"
Documentation/devicetree/bindings/memory.txt | 168 -------------------------
arch/arm/mm/init.c | 3 -
drivers/of/Kconfig | 6 -
drivers/of/Makefile | 1 -
drivers/of/of_reserved_mem.c | 173 --------------------------
drivers/of/platform.c | 4 -
include/linux/of_reserved_mem.h | 14 ---
7 files changed, 369 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/memory.txt
delete mode 100644 drivers/of/of_reserved_mem.c
delete mode 100644 include/linux/of_reserved_mem.h
--
1.7.9.5
In this context, a "doomed" object is an object whose refcount has reached
zero, but that has not yet been freed.
To avoid mutual refcounting vmwgfx need to have a non-refcounted pointer to
a dma-buf in a lookup structure. The pointer is removed in the dma-buf
destructor. To allow lookup-structure private locks we need
get_dma_buf_unless_doomed(). This common refcounting scenario is described
with examples in detail in the kref documentaion.
The solution with local locks is under kref_get_unless_zero().
See also kobject_get_unless_zero() and its commit message.
Since dma-bufs are using the attached file for refcounting,
get_dma_buf_unless_doomed maps directly to a get_file_unless_doomed.
Signed-off-by: Thomas Hellstrom <thellstrom(a)vmware.com>
---
include/linux/dma-buf.h | 16 ++++++++++++++++
include/linux/fs.h | 15 +++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index dfac5ed..6e58144 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -162,6 +162,22 @@ static inline void get_dma_buf(struct dma_buf *dmabuf)
get_file(dmabuf->file);
}
+/**
+ * get_dma_buf_unless_doomed - convenience wrapper for get_file_unless_doomed
+ *
+ * @dmabuf: [in] pointer to dma_buf
+ *
+ * Obtain a dma-buf reference from a lookup structure that doesn't refcount
+ * the dma-buf, but synchronizes with its release method to make sure it has
+ * not been freed yet. See for example kref_get_unless_zero documentation.
+ * Returns true if refcounting succeeds, false otherwise.
+ */
+static inline bool __must_check
+get_dma_buf_unless_doomed(struct dma_buf *dmabuf)
+{
+ return get_file_unless_doomed(dmabuf->file);
+}
+
struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
struct device *dev);
void dma_buf_detach(struct dma_buf *dmabuf,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3f40547..a96c333 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -824,6 +824,21 @@ static inline struct file *get_file(struct file *f)
atomic_long_inc(&f->f_count);
return f;
}
+
+/**
+ * get_file_unless_doomed - convenience wrapper for get_file_unless_doomed
+ * @file: [in] pointer to file
+ *
+ * Obtain a file reference from a lookup structure that doesn't refcount
+ * the file, but synchronizes with its release method to make sure it has
+ * not been freed yet. See for example kref_get_unless_zero documentation.
+ * Returns true if refcounting succeeds, false otherwise.
+ */
+static inline bool __must_check get_file_unless_doomed(struct file *f)
+{
+ return atomic_long_inc_not_zero(&f->f_count) != 0L;
+}
+
#define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1)
#define file_count(x) atomic_long_read(&(x)->f_count)
--
1.7.10.4
op 07-11-13 22:11, Rom Lemarchand schreef:
> Hi Maarten, I tested your changes and needed the attached patch: behavior
> now seems equivalent as android sync. I haven't tested performance.
>
> The issue resolved by this patch happens when i_b < b->num_fences and i_a
>> = a->num_fences (or vice versa). Then, pt_a is invalid and so
> dereferencing pt_a->context causes a crash.
>
Yeah, I pushed my original fix. I intended to keep android userspace behavior the same, and I tried to keep the kernelspace the api same as much as I could. If peformance is the same, or not noticeably worse, would there be any objections on the android side about renaming dma-fence to syncpoint, and getting it in mainline?
~Maarten
op 07-11-13 22:11, Rom Lemarchand schreef:
> Hi Maarten, I tested your changes and needed the attached patch: behavior
> now seems equivalent as android sync. I haven't tested performance.
>
> The issue resolved by this patch happens when i_b < b->num_fences and
> i_a >= a->num_fences (or vice versa). Then, pt_a is invalid and so
> dereferencing pt_a->context causes a crash.
Oops, thinko. :) Originally I had it correct by doing this:
+ /*
+ * Assume sync_fence a and b are both ordered and have no
+ * duplicates with the same context.
+ *
+ * If a sync_fence can only be created with sync_fence_merge
+ * and sync_fence_create, this is a reasonable assumption.
+ */
+ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) {
+ struct fence *pt_a = a->cbs[i_a].sync_pt;
+ struct fence *pt_b = b->cbs[i_b].sync_pt;
+
+ if (pt_a->context < pt_b->context) {
+ sync_fence_add_pt(fence, &i, pt_a);
+
+ i_a++;
+ } else if (pt_a->context > pt_b->context) {
+ sync_fence_add_pt(fence, &i, pt_b);
+
+ i_b++;
+ } else {
+ if (pt_a->seqno - pt_b->seqno <= INT_MAX)
+ sync_fence_add_pt(fence, &i, pt_a);
+ else
+ sync_fence_add_pt(fence, &i, pt_b);
+
+ i_a++;
+ i_b++;
+ }
+ }
+
+ /* Add remaining fences from a or b*/
+ for (; i_a < a->num_fences; i_a++)
+ sync_fence_add_pt(fence, &i, a->cbs[i_a].sync_pt);
+
+ for (; i_b < b->num_fences; i_b++)
+ sync_fence_add_pt(fence, &i, b->cbs[i_b].sync_pt);
Then I thought I could clean it up by merging it, but that ended up being
more unreadable and crashing... so I guess I'll revert back to this version. :)
Anyone else but me that feels such a function could be useful?
My main use-case is that it would resolve the mutual refcounting problem:
1) drm buffer object caches a dma_buf pointer which it refcounts
2) The dma-buf holds a refcount to the buffer.
This is resolved today by having the user-space visible part of the
drm-buffer holding the refcount to the dma_buf. When user-space closes
the drm-buffer, the reference goes away, and eventually the buffer is
freed, when all external dma-buf users are done with the dma-buf
However, this also means that the dma-buf remains for the buffer
lifetime even when there are no external users, which bugs me a bit.
This can be resolved by viewing the drm buffer as a lookup structure
that doesn't hold a refcount to the dma-buf, but that means that the
lookup structure (buffer) would need to share locks with the dma-buf
implementation, unless we have a get_dma_buf_unless_zero, which means we
can use locks local to the lookup structure, the drm buffer.
(See the last part of the kref documentation for a detailed discussion
of this).
Now I don't think keeping the dma_buf for the drm buffer lifetime is a
HUGE problem, but I just wanted to get people's views of this.
Thanks,
Thomas