From: David Herrmann <dh.herrmann@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Subject: [RFC v2 1/3] drm: add pseudo filesystem for shared inodes
Date: Fri, 3 Jan 2014 15:41:25 +0100 [thread overview]
Message-ID: <1388760087-17746-2-git-send-email-dh.herrmann@gmail.com> (raw)
In-Reply-To: <1388760087-17746-1-git-send-email-dh.herrmann@gmail.com>
Our current DRM design uses a single address_space for all users of the
same DRM device. However, there is no way to create an anonymous
address_space without an underlying inode. Therefore, we wait for the
first ->open() callback on a registered char-dev and take-over the inode
of the char-dev. This worked well so far, but has several drawbacks:
- We screw with FS internals and rely on some non-obvious invariants like
inode->i_mapping being the same as inode->i_data for char-devs.
- We don't have any address_space prior to the first ->open() from
user-space. This leads to ugly fallback code and we cannot allocate
global objects early.
As pointed out by Al-Viro, fs/anon_inode.c is *not* supposed to be used by
drivers for anonymous inode-allocation. Therefore, this patch follows the
proposed alternative solution and adds a pseudo filesystem mount-point to
DRM. We can then allocate private inodes including a private address_space
for each DRM device at initialization time.
Note that we could use:
sysfs_get_inode(sysfs_mnt->mnt_sb, drm_device->dev->kobj.sd);
to get access to the underlying sysfs-inode of a "struct device" object.
However, most of this information is currently hidden and it's not clear
whether this address_space is suitable for driver access. Thus, unless
linux allows anonymous address_space objects or driver-core provides a
public inode per device, we're left with our own private internal mount
point.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/gpu/drm/drm_drv.c | 37 +++++++++++++++++++++++++++++++++++++
include/drm/drmP.h | 1 +
2 files changed, 38 insertions(+)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 345be03..48ee03f 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -49,6 +49,8 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
#include <drm/drmP.h>
#include <drm/drm_core.h>
@@ -171,6 +173,30 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
+static struct vfsmount *drm_mnt;
+
+struct inode *drm_alloc_inode(void)
+{
+ return alloc_anon_inode(drm_mnt->mnt_sb);
+}
+
+static const struct dentry_operations drm_dops = {
+ .d_dname = simple_dname,
+};
+
+static struct dentry *drm_mount(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data)
+{
+ return mount_pseudo(fs_type, "drm:", NULL, &drm_dops, 0x010203ff);
+}
+
+static struct file_system_type drm_fs = {
+ .name = "drm",
+ .owner = THIS_MODULE,
+ .mount = drm_mount,
+ .kill_sb = kill_anon_super,
+};
+
/** File operations structure */
static const struct file_operations drm_stub_fops = {
.owner = THIS_MODULE,
@@ -203,9 +229,19 @@ static int __init drm_core_init(void)
goto err_p3;
}
+ drm_mnt = kern_mount(&drm_fs);
+ if (IS_ERR(drm_mnt)) {
+ ret = PTR_ERR(drm_mnt);
+ DRM_ERROR("Cannot mount pseudo fs: %d\n", ret);
+ goto err_p4;
+ }
+
DRM_INFO("Initialized %s %d.%d.%d %s\n",
CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
return 0;
+
+err_p4:
+ debugfs_remove(drm_debugfs_root);
err_p3:
drm_sysfs_destroy();
err_p2:
@@ -218,6 +254,7 @@ err_p1:
static void __exit drm_core_exit(void)
{
+ kern_unmount(drm_mnt);
debugfs_remove(drm_debugfs_root);
drm_sysfs_destroy();
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 2fe9b5d..02637a5 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1258,6 +1258,7 @@ extern long drm_ioctl(struct file *filp,
extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_lastclose(struct drm_device *dev);
+extern struct inode *drm_alloc_inode(void);
/* Device support (drm_fops.h) */
extern struct mutex drm_global_mutex;
--
1.8.5.2
next prev parent reply other threads:[~2014-01-03 14:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-03 14:41 [RFC v2 0/3] DRM Anonymous Inodes David Herrmann
2014-01-03 14:41 ` David Herrmann [this message]
2014-01-03 14:41 ` [RFC v2 2/3] drm: use anon-inode instead of relying on cdevs David Herrmann
2014-01-03 14:41 ` [RFC v2 3/3] drm: init TTM dev_mapping in ttm_bo_device_init() David Herrmann
2014-01-16 11:29 ` [RFC v2 0/3] DRM Anonymous Inodes David Herrmann
2014-01-16 11:51 ` Thomas Hellstrom
2014-01-20 2:00 ` Dave Airlie
2014-01-20 13:55 ` David Herrmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1388760087-17746-2-git-send-email-dh.herrmann@gmail.com \
--to=dh.herrmann@gmail.com \
--cc=daniel.vetter@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.