On Thu, Apr 21, 2011 at 5:55 AM, Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com> wrote:
On 04/21/2011 02:15 PM, Arnd Bergmann wrote:
On Wednesday 20 April 2011, Marcus Lorentzon wrote:
 
On 04/20/2011 06:19 PM, Arnd Bergmann wrote:
   
File descriptors have a number of very nice properties that we can use:

* Efficient lookup in system calls

     
If both use the idr I don't see how fds are faster than ints.
   
File descriptors don't use idr.

 
My mistake, but still, ints could use an array too, and idr or lookup in general should not be an efficiency problem anyway.

* Established ways to pass them around

     
What could be easier than passing an int? I just don't like the
"feature" of passing fds where they are dup-ed without driver knowing
so. If you want to store process specific info associated with the fd
you have to use a list since you don't know if the app sends the fd to
another process. Probably not a big deal, but I don't like it ;)
   
The problem with passing an integer is that it doesn't have any
concept of ownership or lifetime rules.
 

The idea of passing global ids should not affect lifetime. These ints are still lifetime controlled by the "fd" device that created them. So I think they do have a defined lifetime, that of whatever device this int is registered in. And if the process is shut down, all buffers registered in the drm/v4l2 device fd will be released and even freed if it was the last ref.
And if you mean lifetime while process is still alive, even fds has to be closed, and ints has to be closed/unregistered using ioctl. And this is not something that is used by applications either, these refs and allocs are handled by the user space drivers, like libEGL / libGL / X-drivers etc, so ioctl vs. close should not matter.

The problem isn't managing their lifetime in the side that created the buffer, it's managing it while they are in flight.  What happens if process 1 passes a buffer to process 2 and before process 2 takes a reference to it, process 1 crashes?  Some central clearing house has to handle that.  I'm guessing that's the X server in the X case.  In my proposal that's handled by the extra reference being held by the passed fd itself (ie the kernel has a reference as long as the file struct exists in either processes file descriptor table).   
 

If you allow any process access to all integers, a malicious process
might be able to guess it unless you use long cryptographic random
numbers.

 
That's why you put a security model on top. Like GEM auth (which only have access all or nothing) or something like HWMEM where each buffer/id has read/write/import rights per process. This is also easier to trace/debug security since driver is notified when a buffer is transfered to another process. You never get this info from binder/pipe (dup-ed).

It's totally trivial to have debug info on what buffers are currently mapped into what processes.  The kernel knows where all the memory manager's file descriptors have gone.  This is already implemented in the proposal I posted.  From userspace security becomes really simple, a process owns all the buffers it's created and any that have been shared with it.  If it doesn't want to share a buffer with another process, it doesn't pass it to it.  
 

When you have a file descriptor, you can assume that the object
is still alive until you close it. With an integer passed by some
other application, that is less clear.

 
That's why I prefer the register/import global id step with device. It gives the driver a chance to store meta data and prepare to use this buffer. If this has to be done for every device ioctl call, you loose efficiency and all device APIs would have to be updated with cloned ops for fds. Register/import an fd/globalid and then use device local handles is much more efficient and don't require API changes, only additions.

That's exactly what I'm proposing, you import an fd that's been passed to you. 
 

* Allows arbitrary subsystems to create compatible handles. Like a
   socket can be provided by unrelated subsystems, this file handle
   could be created by any of GEM, v4l, tmpfs, ... and we can have
   operations that each of them provides as callbacks

     
Global ids should also be "compatible", since they are from the same
name space. But what do you mean by callbacks? In kernel API on buffer
objects? If so, idr_find(ID)->buffer_struct->callback() should be
similar to idr_find(FD)->file_struct->callback()
   
In the idr example, the modules all need to link to the code that
provides does the DEFINE_IDR(), in the file example, they only
need to provide the same interfaces, so the modules need not link
against any common code other than the VFS.

Not a major point though.
 
True, but I would prefer an in kernel API or callback ifc to do the "mem ops" like resolve.

Most of this can be seen in code @ http://git.linaro.org/gitweb?p=bsp/st-ericsson/linux-2.6.35-ux500.git;a=tree;f=drivers/misc/hwmem;hb=HEAD . But the idea is very close to GEM, actually we just needed a few lines of code in our KMS proto to use HWMEM in KMS & Wayland without changes to user space drm protocols and libs. But note that I'm not promoting HWMEM for unified mem driver, only showing some concepts that could be employed in GEM for use in Android & Wayland with common driver (I consider X "dead" in embedded ;).

/BR
/Marcus



_______________________________________________
Linaro-mm-sig mailing list
Linaro-mm-sig@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-mm-sig