mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
ion: dmabuf improve debugfs
Improvements made to ION to add an additional debugfs file to display allocation/reference information for all ION buffers. rb tree was deleted becaused of unused, add it back to track ion buffer alloc. Migrated from (CR): https://gerrit.mot.com/#/c/1535657/ https://gerrit.mot.com/#/c/1535658/ Change-Id: I1e42d3dac61d4fc856ba8d749cfd2123e40529d9 Signed-off-by: liuwang2 <liuwang2@lenovo.com> Reviewed-on: https://gerrit.mot.com/1811670 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhilong Wang <wangzl30@motorola.com> Reviewed-by: Ji Zhao <zhaoji1@lenovo.com> Reviewed-by: Bolei Shang <shangbl1@lenovo.com> Reviewed-by: Zilong Zhang <zhangzl7@lenovo.com> Reviewed-by: Dawei Wang <wangdw10@motorola.com> Reviewed-by: Zhenxin Xi <xizx@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
c1649eb8f9
commit
5b298f511c
8 changed files with 147 additions and 1 deletions
|
|
@ -434,6 +434,10 @@ static long dma_buf_ioctl(struct file *file,
|
|||
|
||||
return ret;
|
||||
|
||||
case DMA_BUF_IOCTL_IMPORT_BUF_ADD_BY_MOTO:
|
||||
dmabuf->ops->import_buf_add_by_moto(dmabuf);
|
||||
return 0;
|
||||
|
||||
case DMA_BUF_SET_NAME_A:
|
||||
case DMA_BUF_SET_NAME_B:
|
||||
return dma_buf_set_name(dmabuf, (const char __user *)arg);
|
||||
|
|
|
|||
|
|
@ -481,6 +481,54 @@ static int ion_init_sysfs(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ion_debug_allbufs_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct ion_device *dev = s->private;
|
||||
struct rb_node *n;
|
||||
int i;
|
||||
unsigned long total_len = 0;
|
||||
|
||||
seq_printf(s, "%16.s %16.s %12.s %12.s %20.s %s\n", "heap",
|
||||
"buffer", "size", "ref cnt", "allocator", "references");
|
||||
|
||||
down_read(&dev->lock);
|
||||
mutex_lock(&dev->buffer_lock);
|
||||
for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
|
||||
struct ion_buffer *buf = rb_entry(n, struct ion_buffer, node);
|
||||
int buf_refcount = buf->ref_cnt;
|
||||
total_len += buf->size;
|
||||
seq_printf(s, "%16.s %16pK %12.x %12.d %20.d %s",
|
||||
buf->heap->name, buf, (int)buf->size,
|
||||
buf_refcount, buf->pid, "");
|
||||
|
||||
for(i = 0; i < buf->ref_cnt && i < MAX_CLIENTS_NUM; i++)
|
||||
seq_printf(s, "%u, ", buf->client_pids[i]);
|
||||
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
|
||||
if (s->file && s->file->f_path.dentry
|
||||
&& !strcmp(s->file->f_path.dentry->d_iname, "check_all_bufs_total"))
|
||||
seq_printf(s, "%16.s %s is: %lld(%lld KB)\n",
|
||||
"heap", "total size", total_len, total_len/1024);
|
||||
|
||||
mutex_unlock(&dev->buffer_lock);
|
||||
up_read(&dev->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ion_debug_allbufs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, ion_debug_allbufs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations debug_allbufs_fops = {
|
||||
.open = ion_debug_allbufs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int ion_device_create(void)
|
||||
{
|
||||
struct ion_device *idev;
|
||||
|
|
@ -506,10 +554,18 @@ static int ion_device_create(void)
|
|||
goto err_sysfs;
|
||||
}
|
||||
|
||||
idev->buffers = RB_ROOT;
|
||||
mutex_init(&idev->buffer_lock);
|
||||
idev->debug_root = debugfs_create_dir("ion", NULL);
|
||||
init_rwsem(&idev->lock);
|
||||
plist_head_init(&idev->heaps);
|
||||
internal_dev = idev;
|
||||
|
||||
debugfs_create_file("check_all_bufs", 0664, idev->debug_root, idev,
|
||||
&debug_allbufs_fops);
|
||||
debugfs_create_file("check_all_bufs_total", 0664, idev->debug_root, idev,
|
||||
&debug_allbufs_fops);
|
||||
|
||||
return 0;
|
||||
|
||||
err_sysfs:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,31 @@ static void track_buffer_destroyed(struct ion_buffer *buffer)
|
|||
trace_ion_stat(buffer->sg_table, -buffer->size, total);
|
||||
}
|
||||
|
||||
/* this function should only be called while dev->buffer_lock is held */
|
||||
static void ion_buffer_add(struct ion_device *dev, struct ion_buffer *buffer)
|
||||
{
|
||||
struct rb_node **p = &dev->buffers.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct ion_buffer *entry;
|
||||
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
entry = rb_entry(parent, struct ion_buffer, node);
|
||||
|
||||
if (buffer < entry) {
|
||||
p = &(*p)->rb_left;
|
||||
} else if (buffer > entry) {
|
||||
p = &(*p)->rb_right;
|
||||
} else {
|
||||
pr_err("%s: buffer already found.", __func__);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
rb_link_node(&buffer->node, parent, p);
|
||||
rb_insert_color(&buffer->node, &dev->buffers);
|
||||
}
|
||||
|
||||
/* this function should only be called while dev->lock is held */
|
||||
static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
|
||||
struct ion_device *dev,
|
||||
|
|
@ -84,6 +109,14 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
|
|||
INIT_LIST_HEAD(&buffer->attachments);
|
||||
mutex_init(&buffer->lock);
|
||||
track_buffer_created(buffer);
|
||||
|
||||
mutex_lock(&dev->buffer_lock);
|
||||
ion_buffer_add(dev, buffer);
|
||||
mutex_unlock(&dev->buffer_lock);
|
||||
|
||||
buffer->pid = task_pid_nr(current->group_leader);
|
||||
buffer->client_pids[buffer->ref_cnt++] = buffer->pid;
|
||||
|
||||
return buffer;
|
||||
|
||||
err1:
|
||||
|
|
@ -240,6 +273,10 @@ int ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->buffer_lock);
|
||||
rb_erase(&buffer->node, &dev->buffers);
|
||||
mutex_unlock(&dev->buffer_lock);
|
||||
|
||||
heap = buffer->heap;
|
||||
track_buffer_destroyed(buffer);
|
||||
|
||||
|
|
|
|||
|
|
@ -259,6 +259,28 @@ static void *ion_dma_buf_map(struct dma_buf *dmabuf, unsigned long offset)
|
|||
return ion_buffer_kmap_get(buffer) + offset * PAGE_SIZE;
|
||||
}
|
||||
|
||||
static int ion_dma_buf_import_buf_add_by_moto(struct dma_buf *dmabuf)
|
||||
{
|
||||
struct ion_buffer *buffer = dmabuf->priv;
|
||||
int i;
|
||||
int found_pid = 0;
|
||||
pid_t task_pid = task_pid_nr(current->group_leader);
|
||||
|
||||
mutex_lock(&buffer->lock);
|
||||
for (i = 0; i < buffer->ref_cnt && i < MAX_CLIENTS_NUM; i++) {
|
||||
if (buffer->client_pids[i] == task_pid) {
|
||||
found_pid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_pid && buffer->ref_cnt < MAX_CLIENTS_NUM)
|
||||
buffer->client_pids[buffer->ref_cnt++] = task_pid;
|
||||
|
||||
mutex_unlock(&buffer->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
|
||||
{
|
||||
struct ion_buffer *buffer = dmabuf->priv;
|
||||
|
|
@ -278,6 +300,8 @@ static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
|
|||
mutex_unlock(&buffer->lock);
|
||||
}
|
||||
|
||||
ion_dma_buf_import_buf_add_by_moto(dmabuf);
|
||||
|
||||
if (ret)
|
||||
pr_err("%s: failure mapping buffer to userspace\n", __func__);
|
||||
|
||||
|
|
@ -353,6 +377,7 @@ static const struct dma_buf_ops dma_buf_ops = {
|
|||
.vmap = ion_dma_buf_vmap,
|
||||
.vunmap = ion_dma_buf_vunmap,
|
||||
.get_flags = ion_dma_buf_get_flags,
|
||||
.import_buf_add_by_moto = ion_dma_buf_import_buf_add_by_moto,
|
||||
};
|
||||
|
||||
struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
/**
|
||||
* struct ion_device - the metadata of the ion device node
|
||||
* @buffers: an rb tree of all the existing buffers
|
||||
* @buffer_lock: lock protecting the tree of buffers
|
||||
* @dev: the actual misc device
|
||||
* @lock: rwsem protecting the tree of heaps, heap_bitmap and
|
||||
* clients
|
||||
|
|
@ -32,6 +34,8 @@ struct ion_device {
|
|||
struct plist_head heaps;
|
||||
struct dentry *debug_root;
|
||||
int heap_cnt;
|
||||
struct rb_root buffers;
|
||||
struct mutex buffer_lock;
|
||||
};
|
||||
|
||||
/* ion_buffer manipulators */
|
||||
|
|
|
|||
|
|
@ -348,6 +348,16 @@ struct dma_buf_ops {
|
|||
* will be populated with the buffer's flags.
|
||||
*/
|
||||
int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags);
|
||||
|
||||
/**
|
||||
* @import_buf_add_by_moto:
|
||||
*
|
||||
* This is called by gr_ion_alloc added by Motorola
|
||||
*
|
||||
* Returns:
|
||||
* always return 0
|
||||
*/
|
||||
int (*import_buf_add_by_moto)(struct dma_buf *);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -20,8 +20,11 @@
|
|||
#include <linux/types.h>
|
||||
#include <uapi/linux/ion.h>
|
||||
|
||||
#define MAX_CLIENTS_NUM 16
|
||||
|
||||
/**
|
||||
* struct ion_buffer - metadata for a particular buffer
|
||||
* @node: node in the ion_device buffers tree
|
||||
* @list: element in list of deferred freeable buffers
|
||||
* @heap: back pointer to the heap the buffer came from
|
||||
* @flags: buffer specific flags
|
||||
|
|
@ -36,7 +39,10 @@
|
|||
* @attachments: list of devices attached to this buffer
|
||||
*/
|
||||
struct ion_buffer {
|
||||
struct list_head list;
|
||||
union {
|
||||
struct rb_node node;
|
||||
struct list_head list;
|
||||
};
|
||||
struct ion_heap *heap;
|
||||
unsigned long flags;
|
||||
unsigned long private_flags;
|
||||
|
|
@ -47,6 +53,9 @@ struct ion_buffer {
|
|||
void *vaddr;
|
||||
struct sg_table *sg_table;
|
||||
struct list_head attachments;
|
||||
pid_t pid;
|
||||
pid_t client_pids[MAX_CLIENTS_NUM];
|
||||
int ref_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct dma_buf_sync {
|
|||
|
||||
#define DMA_BUF_BASE 'b'
|
||||
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
|
||||
#define DMA_BUF_IOCTL_IMPORT_BUF_ADD_BY_MOTO _IO(DMA_BUF_BASE, 0xCC)
|
||||
|
||||
/* 32/64bitness of this uapi was botched in android, there's no difference
|
||||
* between them in actual uapi, they're just different numbers.
|
||||
|
|
|
|||
Loading…
Reference in a new issue