Commit 15c6098c authored by Laura Abbott's avatar Laura Abbott Committed by Greg Kroah-Hartman

staging: android: ion: Remove ion_handle and ion_client

ion_handle was introduced as an abstraction to represent a reference to
a buffer via an ion_client. As frameworks outside of Ion evolved, the dmabuf
emerged as the preferred standard for use in the kernel. This has made
the ion_handle an unnecessary abstraction and prone to race
conditions. ion_client is also now only used internally. We have enough
mechanisms for race conditions and leaks already so just drop ion_handle
and ion_client. This also includes ripping out most of the debugfs
infrastructure since much of that was tied to clients and handles.
The debugfs infrastructure was prone to give confusing data (orphaned
allocations) so it can be replaced with something better if people
actually want it.
Signed-off-by: default avatarLaura Abbott <labbott@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e3b914bc
...@@ -21,9 +21,7 @@ ...@@ -21,9 +21,7 @@
#include "ion.h" #include "ion.h"
union ion_ioctl_arg { union ion_ioctl_arg {
struct ion_fd_data fd;
struct ion_allocation_data allocation; struct ion_allocation_data allocation;
struct ion_handle_data handle;
struct ion_heap_query query; struct ion_heap_query query;
}; };
...@@ -48,8 +46,6 @@ static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) ...@@ -48,8 +46,6 @@ static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg)
static unsigned int ion_ioctl_dir(unsigned int cmd) static unsigned int ion_ioctl_dir(unsigned int cmd)
{ {
switch (cmd) { switch (cmd) {
case ION_IOC_FREE:
return _IOC_WRITE;
default: default:
return _IOC_DIR(cmd); return _IOC_DIR(cmd);
} }
...@@ -57,8 +53,6 @@ static unsigned int ion_ioctl_dir(unsigned int cmd) ...@@ -57,8 +53,6 @@ static unsigned int ion_ioctl_dir(unsigned int cmd)
long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ {
struct ion_client *client = filp->private_data;
struct ion_handle *cleanup_handle = NULL;
int ret = 0; int ret = 0;
unsigned int dir; unsigned int dir;
union ion_ioctl_arg data; union ion_ioctl_arg data;
...@@ -86,61 +80,28 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -86,61 +80,28 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case ION_IOC_ALLOC: case ION_IOC_ALLOC:
{ {
struct ion_handle *handle; int fd;
handle = ion_alloc(client, data.allocation.len, fd = ion_alloc(data.allocation.len,
data.allocation.heap_id_mask, data.allocation.heap_id_mask,
data.allocation.flags); data.allocation.flags);
if (IS_ERR(handle)) if (fd < 0)
return PTR_ERR(handle); return fd;
data.allocation.handle = handle->id; data.allocation.fd = fd;
cleanup_handle = handle;
break;
}
case ION_IOC_FREE:
{
struct ion_handle *handle;
mutex_lock(&client->lock);
handle = ion_handle_get_by_id_nolock(client,
data.handle.handle);
if (IS_ERR(handle)) {
mutex_unlock(&client->lock);
return PTR_ERR(handle);
}
ion_free_nolock(client, handle);
ion_handle_put_nolock(handle);
mutex_unlock(&client->lock);
break;
}
case ION_IOC_SHARE:
{
struct ion_handle *handle;
handle = ion_handle_get_by_id(client, data.handle.handle);
if (IS_ERR(handle))
return PTR_ERR(handle);
data.fd.fd = ion_share_dma_buf_fd(client, handle);
ion_handle_put(handle);
if (data.fd.fd < 0)
ret = data.fd.fd;
break; break;
} }
case ION_IOC_HEAP_QUERY: case ION_IOC_HEAP_QUERY:
ret = ion_query_heaps(client, &data.query); ret = ion_query_heaps(&data.query);
break; break;
default: default:
return -ENOTTY; return -ENOTTY;
} }
if (dir & _IOC_READ) { if (dir & _IOC_READ) {
if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd)))
if (cleanup_handle)
ion_free(client, cleanup_handle);
return -EFAULT; return -EFAULT;
} }
}
return ret; return ret;
} }
This diff is collapsed.
...@@ -78,7 +78,6 @@ struct ion_platform_heap { ...@@ -78,7 +78,6 @@ struct ion_platform_heap {
* handle, used for debugging * handle, used for debugging
*/ */
struct ion_buffer { struct ion_buffer {
struct kref ref;
union { union {
struct rb_node node; struct rb_node node;
struct list_head list; struct list_head list;
...@@ -109,8 +108,6 @@ void ion_buffer_destroy(struct ion_buffer *buffer); ...@@ -109,8 +108,6 @@ void ion_buffer_destroy(struct ion_buffer *buffer);
* @buffers: an rb tree of all the existing buffers * @buffers: an rb tree of all the existing buffers
* @buffer_lock: lock protecting the tree of buffers * @buffer_lock: lock protecting the tree of buffers
* @lock: rwsem protecting the tree of heaps and clients * @lock: rwsem protecting the tree of heaps and clients
* @heaps: list of all the heaps in the system
* @user_clients: list of all the clients created from userspace
*/ */
struct ion_device { struct ion_device {
struct miscdevice dev; struct miscdevice dev;
...@@ -118,64 +115,10 @@ struct ion_device { ...@@ -118,64 +115,10 @@ struct ion_device {
struct mutex buffer_lock; struct mutex buffer_lock;
struct rw_semaphore lock; struct rw_semaphore lock;
struct plist_head heaps; struct plist_head heaps;
struct rb_root clients;
struct dentry *debug_root; struct dentry *debug_root;
struct dentry *heaps_debug_root;
struct dentry *clients_debug_root;
int heap_cnt; int heap_cnt;
}; };
/**
* struct ion_client - a process/hw block local address space
* @node: node in the tree of all clients
* @dev: backpointer to ion device
* @handles: an rb tree of all the handles in this client
* @idr: an idr space for allocating handle ids
* @lock: lock protecting the tree of handles
* @name: used for debugging
* @display_name: used for debugging (unique version of @name)
* @display_serial: used for debugging (to make display_name unique)
* @task: used for debugging
*
* A client represents a list of buffers this client may access.
* The mutex stored here is used to protect both handles tree
* as well as the handles themselves, and should be held while modifying either.
*/
struct ion_client {
struct rb_node node;
struct ion_device *dev;
struct rb_root handles;
struct idr idr;
struct mutex lock;
const char *name;
char *display_name;
int display_serial;
struct task_struct *task;
pid_t pid;
struct dentry *debug_root;
};
/**
* ion_handle - a client local reference to a buffer
* @ref: reference count
* @client: back pointer to the client the buffer resides in
* @buffer: pointer to the buffer
* @node: node in the client's handle rbtree
* @kmap_cnt: count of times this client has mapped to kernel
* @id: client-unique id allocated by client->idr
*
* Modifications to node, map_cnt or mapping should be protected by the
* lock in the client. Other fields are never changed after initialization.
*/
struct ion_handle {
struct kref ref;
struct ion_client *client;
struct ion_buffer *buffer;
struct rb_node node;
unsigned int kmap_cnt;
int id;
};
/** /**
* struct ion_heap_ops - ops to operate on a given heap * struct ion_heap_ops - ops to operate on a given heap
* @allocate: allocate memory * @allocate: allocate memory
...@@ -296,14 +239,10 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, ...@@ -296,14 +239,10 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
int ion_heap_buffer_zero(struct ion_buffer *buffer); int ion_heap_buffer_zero(struct ion_buffer *buffer);
int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot);
struct ion_handle *ion_alloc(struct ion_client *client, size_t len, int ion_alloc(size_t len,
unsigned int heap_id_mask, unsigned int heap_id_mask,
unsigned int flags); unsigned int flags);
void ion_free(struct ion_client *client, struct ion_handle *handle);
int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle);
/** /**
* ion_heap_init_shrinker * ion_heap_init_shrinker
* @heap: the heap * @heap: the heap
...@@ -431,18 +370,6 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, ...@@ -431,18 +370,6 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client, int ion_query_heaps(struct ion_heap_query *query);
int id);
void ion_free_nolock(struct ion_client *client, struct ion_handle *handle);
int ion_handle_put_nolock(struct ion_handle *handle);
struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
int id);
int ion_handle_put(struct ion_handle *handle);
int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query);
#endif /* _ION_H */ #endif /* _ION_H */
...@@ -85,31 +85,8 @@ struct ion_allocation_data { ...@@ -85,31 +85,8 @@ struct ion_allocation_data {
__u64 len; __u64 len;
__u32 heap_id_mask; __u32 heap_id_mask;
__u32 flags; __u32 flags;
__u32 handle;
__u32 unused;
};
/**
* struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair
* @handle: a handle
* @fd: a file descriptor representing that handle
*
* For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
* the handle returned from ion alloc, and the kernel returns the file
* descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace
* provides the file descriptor and the kernel returns the handle.
*/
struct ion_fd_data {
__u32 handle;
__u32 fd; __u32 fd;
}; __u32 unused;
/**
* struct ion_handle_data - a handle passed to/from the kernel
* @handle: a handle
*/
struct ion_handle_data {
__u32 handle;
}; };
#define MAX_HEAP_NAME 32 #define MAX_HEAP_NAME 32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment