Received: by 2002:ac0:8845:0:0:0:0:0 with SMTP id g63csp1342147img; Tue, 26 Feb 2019 19:55:40 -0800 (PST) X-Google-Smtp-Source: AHgI3IYhAWE44mtU1cJ/fNpbO3J7/xB9eHJoamJmYzyv/5cqmb36mmwqFt7IbVrzYqMSJ5f9sDhX X-Received: by 2002:a65:60d8:: with SMTP id r24mr983898pgv.6.1551239740845; Tue, 26 Feb 2019 19:55:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551239740; cv=none; d=google.com; s=arc-20160816; b=PlXhQpWlI9jyAnrWum3wdq7hrDIx0/geODAlx6mbmgYwX8uhMQG0ymjHrzw+ZmdoyN 14wFYN+W+aQ8cN8eJCZ9Ot3lNYY+u4MykGcSCUaAqPQ3HUj6UjwoBtgDqQbRwBYalGy7 D07rNgayO9BrpbmULEAXdBv4ZBoK/2yQRcQRUQ+CJ6GWTURxTT/8Y8SSOPy7pYgkk3ae wYusPOuaLuuQCPpxGiJ7bp7Cs/N5NmnZwra1hL2g+AswjUa/UA5Fmzi6SrY/ubNUGVQv nyWDjjjovrZhpOWDlI1yggVnQcbUMxmn2L8tNe5xYuW73oYqGbhSO8tPSoolpv8YGL2b pi+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=kKdTjrQBX3Yql3AnN1qxLX/9WJonljdYWNgtBrddlCE=; b=PZCxUKe5ldnYuDkemg1ZMzBrGcCf5x3ElP1P6zaZRlo6UEbOPVM8u/QZmtygHFqH1j y1TzFzcwTbVU+v5Z86+yNzOV9ABJqjEVfX/kKNP28v1YSViPCDJxMaYmdIqu5t8PLl4V GT9LxQYa6WL1UKCNyPdknqHMFPphF+o/t4iQ6Ir0EUeExoEBCBUDLop7HBOfP921ceN3 SgL0kTz8ciait2jZqaTVxZtyb89Lpc+S9zpq+eBkYQ9mr3yzUr/nGoFxCxWiS/fENKuO mKi2xPf/2O9BPZGN4itrsbmuDGcGVRvoJns/4wwG4cQFp1NZz6FLNcBPiw5GSoZXiE3l LIwA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=ObNyAecF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e5si13709331pfi.48.2019.02.26.19.55.25; Tue, 26 Feb 2019 19:55:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=ObNyAecF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729694AbfB0DzA (ORCPT + 99 others); Tue, 26 Feb 2019 22:55:00 -0500 Received: from mail-oi1-f202.google.com ([209.85.167.202]:40593 "EHLO mail-oi1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729662AbfB0Dy6 (ORCPT ); Tue, 26 Feb 2019 22:54:58 -0500 Received: by mail-oi1-f202.google.com with SMTP id z70so6561923oia.7 for ; Tue, 26 Feb 2019 19:54:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=kKdTjrQBX3Yql3AnN1qxLX/9WJonljdYWNgtBrddlCE=; b=ObNyAecF8hK2EvDirYGZliL4JU433V46Y4lVZLAdxq6SSa9sBlmsjKEba1KVT3Ot3R ke7l8Rb7ghv+XgR4m3GfcSEzRE+I50KbeLlD/IsggDAN0+V9lEitR3biuUdv07MeI+xq pn4vl+FXdQIXe7SYlQM0WJpgHoZMkzAl1pSmzWAumifeEdpT5xE3g+HywOBA7AvFPe+d SIO22CYtBIU1meSJLZ1BrMS92Q/0lzHvBTBieUtTYnZ4eFTS3PdRKKm7iCKtTnJVKMhB xn0HoU9DXCPgLNTm2os+xk4fHzJQRrQRfxpUGl6r67ilK/yJhOB98f2Ql88DAMPWq0ql yCkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=kKdTjrQBX3Yql3AnN1qxLX/9WJonljdYWNgtBrddlCE=; b=XV8ACJvTdUfHUV/YmBMydGazp10p8aGxj6qCyLlBPva7KEIXj8t8hZ++KxJciSCrfi oqkzufpB+FmsXmbbGYgTz63slEbmgnlHn/axf7Tmamch7j2cPb/PeZLoPaUYNEUu+Auc vt1aRPyMjhZMhwuF6BxnJ97vERwUGMO4aOv+Y0nxEA1BsZHt55aectLZBUJfEclyP3RL QW+LWgnfm84gVJu/tYpMVbDYEB52Mh/7WJXy/iDf0Cf+KSpn5LGA+rvPl7tZlj1hZktT oHSQ+5+C63sWTgNOIBtfScBPlT76IWmG9pXVNJO0B/z7l3o5rd8pBbrjhK4XWQuXEhy7 LJjA== X-Gm-Message-State: AHQUAuapw2k5hdq11vuHDETPbeZnXRWObwywWPQY8c2rjTRDl4QCFTzs xFE4JKnYUIFfGiBupIAAgFgoVKR7r3tOt2fwB0K5OHFVisHT1GRnotFZ0eUHXQxOQwJau73m2ig 1mC53UdQS5SLF7O7ySp+i7W4e9Wgo0D8Wma/d6/VfdUpK8vKlwt2JiQX22YfslXyzTW8= X-Received: by 2002:a9d:6f98:: with SMTP id h24mr752342otq.30.1551239698302; Tue, 26 Feb 2019 19:54:58 -0800 (PST) Date: Tue, 26 Feb 2019 19:54:46 -0800 In-Reply-To: <20190227035448.117169-1-fengc@google.com> Message-Id: <20190227035448.117169-2-fengc@google.com> Mime-Version: 1.0 References: <20190227035448.117169-1-fengc@google.com> X-Mailer: git-send-email 2.21.0.rc2.261.ga7da99ff1b-goog Subject: [RFC dma-buf 1/3] dma-buf: give each buffer a full-fledged inode From: Chenbo Feng To: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org Cc: Sumit Semwal , erickreyes@google.com, Greg Hackmann , Chenbo Feng Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Greg Hackmann By traversing /proc/*/fd and /proc/*/map_files, processes with CAP_ADMIN can get a lot of fine-grained data about how shmem buffers are shared among processes. stat(2) on each entry gives the caller a unique ID (st_ino), the buffer's size (st_size), and even the number of pages currently charged to the buffer (st_blocks / 512). In contrast, all dma-bufs share the same anonymous inode. So while we can count how many dma-buf fds or mappings a process has, we can't get the size of the backing buffers or tell if two entries point to the same dma-buf. On systems with debugfs, we can get a per-buffer breakdown of size and reference count, but can't tell which processes are actually holding the references to each buffer. Replace the singleton inode with full-fledged inodes allocated by alloc_anon_inode(). This involves creating and mounting a mini-pseudo-filesystem for dma-buf, following the example in fs/aio.c. Signed-off-by: Greg Hackmann Signed-off-by: Chenbo Feng --- drivers/dma-buf/dma-buf.c | 68 +++++++++++++++++++++++++++++++++----- include/uapi/linux/magic.h | 1 + 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 02f7f9a89979..d72352356ac5 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -34,8 +34,10 @@ #include #include #include +#include #include +#include static inline int is_dma_buf_file(struct file *); @@ -46,6 +48,25 @@ struct dma_buf_list { static struct dma_buf_list db_list; +static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = simple_dname, +}; + +static struct vfsmount *dma_buf_mnt; + +static struct dentry *dma_buf_fs_mount(struct file_system_type *fs_type, + int flags, const char *name, void *data) +{ + return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops, + DMA_BUF_MAGIC); +} + +static struct file_system_type dma_buf_fs_type = { + .name = "dmabuf", + .mount = dma_buf_fs_mount, + .kill_sb = kill_anon_super, +}; + static int dma_buf_release(struct inode *inode, struct file *file) { struct dma_buf *dmabuf; @@ -338,6 +359,34 @@ static inline int is_dma_buf_file(struct file *file) return file->f_op == &dma_buf_fops; } +static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags) +{ + static const struct qstr this = QSTR_INIT("dmabuf", 6); + struct path path; + struct file *file; + struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb); + + if (IS_ERR(inode)) + return ERR_CAST(inode); + + inode->i_size = dmabuf->size; + inode_set_bytes(inode, dmabuf->size); + + file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf", + OPEN_FMODE(flags) | FMODE_LSEEK, + &dma_buf_fops); + if (IS_ERR(file)) + goto err_alloc_file; + file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); + file->private_data = dmabuf; + + return file; + +err_alloc_file: + iput(inode); + return file; +} + /** * DOC: dma buf device access * @@ -433,14 +482,11 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) } dmabuf->resv = resv; - file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, - exp_info->flags); + file = dma_buf_getfile(dmabuf, exp_info->flags); if (IS_ERR(file)) { ret = PTR_ERR(file); goto err_dmabuf; } - - file->f_mode |= FMODE_LSEEK; dmabuf->file = file; mutex_init(&dmabuf->lock); @@ -1025,8 +1071,8 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) return ret; seq_puts(s, "\nDma-buf Objects:\n"); - seq_printf(s, "%-8s\t%-8s\t%-8s\t%-8s\texp_name\n", - "size", "flags", "mode", "count"); + seq_printf(s, "%-8s\t%-8s\t%-8s\t%-8s\texp_name\t%-8s\n", + "size", "flags", "mode", "count", "ino"); list_for_each_entry(buf_obj, &db_list.head, list_node) { ret = mutex_lock_interruptible(&buf_obj->lock); @@ -1037,11 +1083,12 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) continue; } - seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n", + seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\n", buf_obj->size, buf_obj->file->f_flags, buf_obj->file->f_mode, file_count(buf_obj->file), - buf_obj->exp_name); + buf_obj->exp_name, + file_inode(buf_obj->file)->i_ino); robj = buf_obj->resv; while (true) { @@ -1146,6 +1193,10 @@ static inline void dma_buf_uninit_debugfs(void) static int __init dma_buf_init(void) { + dma_buf_mnt = kern_mount(&dma_buf_fs_type); + if (IS_ERR(dma_buf_mnt)) + return PTR_ERR(dma_buf_mnt); + mutex_init(&db_list.lock); INIT_LIST_HEAD(&db_list.head); dma_buf_init_debugfs(); @@ -1156,5 +1207,6 @@ subsys_initcall(dma_buf_init); static void __exit dma_buf_deinit(void) { dma_buf_uninit_debugfs(); + kern_unmount(dma_buf_mnt); } __exitcall(dma_buf_deinit); diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index f8c00045d537..665e18627f78 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -91,5 +91,6 @@ #define UDF_SUPER_MAGIC 0x15013346 #define BALLOON_KVM_MAGIC 0x13661366 #define ZSMALLOC_MAGIC 0x58295829 +#define DMA_BUF_MAGIC 0x444d4142 /* "DMAB" */ #endif /* __LINUX_MAGIC_H__ */ -- 2.21.0.rc2.261.ga7da99ff1b-goog