Message ID | 1465930269-7883-13-git-send-email-daniel.vetter@ffwll.ch (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Jun 14, 2016 at 08:51:07PM +0200, Daniel Vetter wrote: > There can only be one current master, and it's for the overall device. > Render/control minors don't support master-based auth at all. > > This simplifies the master logic a lot, at least in my eyes: All these > additional pointer chases are just confusing. One master for the device, on the struct drm_device, as opposed to hidden behind the first of three minors, makes sense. > @@ -128,13 +128,13 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) > lockdep_assert_held_once(&dev->master_mutex); > > /* create a new master */ > - fpriv->minor->master = drm_master_create(fpriv->minor->dev); > - if (!fpriv->minor->master) > + dev->master = drm_master_create(dev); > + if (!dev->master) > return -ENOMEM; > > /* take another reference for the copy in the local file priv */ > old_master = fpriv->master; > - fpriv->master = drm_master_get(fpriv->minor->master); > + fpriv->master = drm_master_get(dev->master); > > if (dev->driver->master_create) { > ret = dev->driver->master_create(dev, fpriv->master); > @@ -234,10 +234,10 @@ int drm_master_open(struct drm_file *file_priv) > /* if there is no current master make this fd it, but do not create > * any master object for render clients */ > mutex_lock(&dev->master_mutex); > - if (!file_priv->minor->master) > + if (!dev->master) > ret = drm_new_set_master(dev, file_priv); > else > - file_priv->master = drm_master_get(file_priv->minor->master); > + file_priv->master = drm_master_get(dev->master); > mutex_unlock(&dev->master_mutex); You could take the opportunity to make this a bit simpler: if (!READ_ONCE(dev->master)) { int ret; ret = 0; mutex_lock(&dev->master_mutex); if (!dev->master) ret = drm_new_master(dev); mutex_unlock(&dev->master_mutex); if (ret) return ret; } file_priv->master = drm_master_get(dev->master); return 0; Just to straighten out the kref dance. > > return ret; > @@ -271,11 +271,11 @@ void drm_master_release(struct drm_file *file_priv) > mutex_unlock(&dev->struct_mutex); > } > > - if (file_priv->minor->master == file_priv->master) { > + if (dev->master == file_priv->master) { > /* drop the reference held my the minor */ > if (dev->driver->master_drop) > dev->driver->master_drop(dev, file_priv, true); > - drm_master_put(&file_priv->minor->master); > + drm_master_put(&dev->master); This still makes me uneasy. This is not equivalent to dropmaster_ioctl and subsequent setmaster_ioctl will fail as dev->master is still assigned (but the owner has gone). -Chris
On Wed, Jun 15, 2016 at 01:10:35PM +0100, Chris Wilson wrote: > On Tue, Jun 14, 2016 at 08:51:07PM +0200, Daniel Vetter wrote: > > There can only be one current master, and it's for the overall device. > > Render/control minors don't support master-based auth at all. > > > > This simplifies the master logic a lot, at least in my eyes: All these > > additional pointer chases are just confusing. > > One master for the device, on the struct drm_device, as opposed to hidden > behind the first of three minors, makes sense. > > > @@ -128,13 +128,13 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) > > lockdep_assert_held_once(&dev->master_mutex); > > > > /* create a new master */ > > - fpriv->minor->master = drm_master_create(fpriv->minor->dev); > > - if (!fpriv->minor->master) > > + dev->master = drm_master_create(dev); > > + if (!dev->master) > > return -ENOMEM; > > > > /* take another reference for the copy in the local file priv */ > > old_master = fpriv->master; > > - fpriv->master = drm_master_get(fpriv->minor->master); > > + fpriv->master = drm_master_get(dev->master); > > > > if (dev->driver->master_create) { > > ret = dev->driver->master_create(dev, fpriv->master); > > > @@ -234,10 +234,10 @@ int drm_master_open(struct drm_file *file_priv) > > /* if there is no current master make this fd it, but do not create > > * any master object for render clients */ > > mutex_lock(&dev->master_mutex); > > - if (!file_priv->minor->master) > > + if (!dev->master) > > ret = drm_new_set_master(dev, file_priv); > > else > > - file_priv->master = drm_master_get(file_priv->minor->master); > > + file_priv->master = drm_master_get(dev->master); > > mutex_unlock(&dev->master_mutex); > > You could take the opportunity to make this a bit simpler: > > if (!READ_ONCE(dev->master)) { > int ret; > > ret = 0; > mutex_lock(&dev->master_mutex); > if (!dev->master) > ret = drm_new_master(dev); > mutex_unlock(&dev->master_mutex); > if (ret) > return ret; > } > > file_priv->master = drm_master_get(dev->master); drm_master_get(dev->master) must be under the master_mutex, without it we could race with a drm_master_put(&dev->master) and end up doing a kref_get when the refcount already reached 0. > return 0; > > Just to straighten out the kref dance. > > > > > return ret; > > @@ -271,11 +271,11 @@ void drm_master_release(struct drm_file *file_priv) > > mutex_unlock(&dev->struct_mutex); > > } > > > > - if (file_priv->minor->master == file_priv->master) { > > + if (dev->master == file_priv->master) { > > /* drop the reference held my the minor */ > > if (dev->driver->master_drop) > > dev->driver->master_drop(dev, file_priv, true); > > - drm_master_put(&file_priv->minor->master); > > + drm_master_put(&dev->master); > > This still makes me uneasy. This is not equivalent to dropmaster_ioctl > and subsequent setmaster_ioctl will fail as dev->master is still > assigned (but the owner has gone). drm_master_put clears the pointer passed to it, so dev->master will be set to NULL. And it does the same as drop_master (wrt dev->master at least, master_release also needs to clean up file_priv->master on top). Not sure it's worth it to extract those 5 lines into a __drm_drop_master() helper function? I can respin with that if you want. On the master_open/setmaster side the shared code is already extracted in drm_new_set_master(). -Daniel
On Wed, Jun 15, 2016 at 06:01:41PM +0200, Daniel Vetter wrote: > On Wed, Jun 15, 2016 at 01:10:35PM +0100, Chris Wilson wrote: > > On Tue, Jun 14, 2016 at 08:51:07PM +0200, Daniel Vetter wrote: > > > There can only be one current master, and it's for the overall device. > > > Render/control minors don't support master-based auth at all. > > > > > > This simplifies the master logic a lot, at least in my eyes: All these > > > additional pointer chases are just confusing. > > > > One master for the device, on the struct drm_device, as opposed to hidden > > behind the first of three minors, makes sense. > > > > > @@ -128,13 +128,13 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) > > > lockdep_assert_held_once(&dev->master_mutex); > > > > > > /* create a new master */ > > > - fpriv->minor->master = drm_master_create(fpriv->minor->dev); > > > - if (!fpriv->minor->master) > > > + dev->master = drm_master_create(dev); > > > + if (!dev->master) > > > return -ENOMEM; > > > > > > /* take another reference for the copy in the local file priv */ > > > old_master = fpriv->master; > > > - fpriv->master = drm_master_get(fpriv->minor->master); > > > + fpriv->master = drm_master_get(dev->master); > > > > > > if (dev->driver->master_create) { > > > ret = dev->driver->master_create(dev, fpriv->master); > > > > > @@ -234,10 +234,10 @@ int drm_master_open(struct drm_file *file_priv) > > > /* if there is no current master make this fd it, but do not create > > > * any master object for render clients */ > > > mutex_lock(&dev->master_mutex); > > > - if (!file_priv->minor->master) > > > + if (!dev->master) > > > ret = drm_new_set_master(dev, file_priv); > > > else > > > - file_priv->master = drm_master_get(file_priv->minor->master); > > > + file_priv->master = drm_master_get(dev->master); > > > mutex_unlock(&dev->master_mutex); > > > > You could take the opportunity to make this a bit simpler: > > > > if (!READ_ONCE(dev->master)) { > > int ret; > > > > ret = 0; > > mutex_lock(&dev->master_mutex); > > if (!dev->master) > > ret = drm_new_master(dev); > > mutex_unlock(&dev->master_mutex); > > if (ret) > > return ret; > > } > > > > file_priv->master = drm_master_get(dev->master); > > drm_master_get(dev->master) must be under the master_mutex, without it we > could race with a drm_master_put(&dev->master) and end up doing a kref_get > when the refcount already reached 0. Something is very fishy then. The behaviour of drm_new_master() would appear to be to create a drm_master owned by the device, but really it is owned by file_priv? * checks back on drm_master So drm_master is the authentication structure that needs to be unique to a hierachy. So drm_new_set_master() and here really do appear backwards. The old drm_new_set_master() makes more sense, it assigns to the file_priv, and then performs a setmaster operation. In that ordering, you could even do the file_priv local operation of creating the new master structure before taking the lock to perform setmaster. > > Just to straighten out the kref dance. > > > > > > > > return ret; > > > @@ -271,11 +271,11 @@ void drm_master_release(struct drm_file *file_priv) > > > mutex_unlock(&dev->struct_mutex); > > > } > > > > > > - if (file_priv->minor->master == file_priv->master) { > > > + if (dev->master == file_priv->master) { > > > /* drop the reference held my the minor */ > > > if (dev->driver->master_drop) > > > dev->driver->master_drop(dev, file_priv, true); > > > - drm_master_put(&file_priv->minor->master); > > > + drm_master_put(&dev->master); > > > > This still makes me uneasy. This is not equivalent to dropmaster_ioctl > > and subsequent setmaster_ioctl will fail as dev->master is still > > assigned (but the owner has gone). > > drm_master_put clears the pointer passed to it, so dev->master will be set > to NULL. And it does the same as drop_master (wrt dev->master at least, > master_release also needs to clean up file_priv->master on top). Not sure > it's worth it to extract those 5 lines into a __drm_drop_master() helper > function? I can respin with that if you want. On the master_open/setmaster > side the shared code is already extracted in drm_new_set_master(). drm_master_put() nullifies, didn't expect that. -Chris
On Wed, Jun 15, 2016 at 6:33 PM, Chris Wilson <chris@chris-wilson.co.uk> wrote: > On Wed, Jun 15, 2016 at 06:01:41PM +0200, Daniel Vetter wrote: >> On Wed, Jun 15, 2016 at 01:10:35PM +0100, Chris Wilson wrote: >> > On Tue, Jun 14, 2016 at 08:51:07PM +0200, Daniel Vetter wrote: >> > > There can only be one current master, and it's for the overall device. >> > > Render/control minors don't support master-based auth at all. >> > > >> > > This simplifies the master logic a lot, at least in my eyes: All these >> > > additional pointer chases are just confusing. >> > >> > One master for the device, on the struct drm_device, as opposed to hidden >> > behind the first of three minors, makes sense. >> > >> > > @@ -128,13 +128,13 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) >> > > lockdep_assert_held_once(&dev->master_mutex); >> > > >> > > /* create a new master */ >> > > - fpriv->minor->master = drm_master_create(fpriv->minor->dev); >> > > - if (!fpriv->minor->master) >> > > + dev->master = drm_master_create(dev); >> > > + if (!dev->master) >> > > return -ENOMEM; >> > > >> > > /* take another reference for the copy in the local file priv */ >> > > old_master = fpriv->master; >> > > - fpriv->master = drm_master_get(fpriv->minor->master); >> > > + fpriv->master = drm_master_get(dev->master); >> > > >> > > if (dev->driver->master_create) { >> > > ret = dev->driver->master_create(dev, fpriv->master); >> > >> > > @@ -234,10 +234,10 @@ int drm_master_open(struct drm_file *file_priv) >> > > /* if there is no current master make this fd it, but do not create >> > > * any master object for render clients */ >> > > mutex_lock(&dev->master_mutex); >> > > - if (!file_priv->minor->master) >> > > + if (!dev->master) >> > > ret = drm_new_set_master(dev, file_priv); >> > > else >> > > - file_priv->master = drm_master_get(file_priv->minor->master); >> > > + file_priv->master = drm_master_get(dev->master); >> > > mutex_unlock(&dev->master_mutex); >> > >> > You could take the opportunity to make this a bit simpler: >> > >> > if (!READ_ONCE(dev->master)) { >> > int ret; >> > >> > ret = 0; >> > mutex_lock(&dev->master_mutex); >> > if (!dev->master) >> > ret = drm_new_master(dev); >> > mutex_unlock(&dev->master_mutex); >> > if (ret) >> > return ret; >> > } >> > >> > file_priv->master = drm_master_get(dev->master); >> >> drm_master_get(dev->master) must be under the master_mutex, without it we >> could race with a drm_master_put(&dev->master) and end up doing a kref_get >> when the refcount already reached 0. > > Something is very fishy then. The behaviour of drm_new_master() would > appear to be to create a drm_master owned by the device, but really it is > owned by file_priv? > > * checks back on drm_master > > So drm_master is the authentication structure that needs to be unique to > a hierachy. So drm_new_set_master() and here really do appear backwards. > > The old drm_new_set_master() makes more sense, it assigns to the > file_priv, and then performs a setmaster operation. In that ordering, > you could even do the file_priv local operation of creating the new > master structure before taking the lock to perform setmaster. I didn't change the logic, the old new_set_master didn't first create the master for file_priv, it first created it for file_priv->minor, and that drm_minor is the device-unique drm_minor for the primary/legacy node. The change only moves from that drm_minor for the legacy node to the drm_device. Wrt refences, every file_priv holds a ref for it's master. On top of that the current master structure (after this patch stored in dev->master, before in dev->minors[legacy]->master. The only tricky bit is that when the current master closes, we do an implicit dropmaster first. -Daniel
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 94761e4bd1e5..fcadd8e1de28 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -128,13 +128,13 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) lockdep_assert_held_once(&dev->master_mutex); /* create a new master */ - fpriv->minor->master = drm_master_create(fpriv->minor->dev); - if (!fpriv->minor->master) + dev->master = drm_master_create(dev); + if (!dev->master) return -ENOMEM; /* take another reference for the copy in the local file priv */ old_master = fpriv->master; - fpriv->master = drm_master_get(fpriv->minor->master); + fpriv->master = drm_master_get(dev->master); if (dev->driver->master_create) { ret = dev->driver->master_create(dev, fpriv->master); @@ -157,7 +157,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) out_err: /* drop both references and restore old master on failure */ - drm_master_put(&fpriv->minor->master); + drm_master_put(&dev->master); drm_master_put(&fpriv->master); fpriv->master = old_master; @@ -173,7 +173,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, if (file_priv->is_master) goto out_unlock; - if (file_priv->minor->master) { + if (dev->master) { ret = -EINVAL; goto out_unlock; } @@ -188,13 +188,13 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, goto out_unlock; } - file_priv->minor->master = drm_master_get(file_priv->master); + dev->master = drm_master_get(file_priv->master); file_priv->is_master = 1; if (dev->driver->master_set) { ret = dev->driver->master_set(dev, file_priv, false); if (unlikely(ret != 0)) { file_priv->is_master = 0; - drm_master_put(&file_priv->minor->master); + drm_master_put(&dev->master); } } @@ -212,13 +212,13 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, if (!file_priv->is_master) goto out_unlock; - if (!file_priv->minor->master) + if (!dev->master) goto out_unlock; ret = 0; if (dev->driver->master_drop) dev->driver->master_drop(dev, file_priv, false); - drm_master_put(&file_priv->minor->master); + drm_master_put(&dev->master); file_priv->is_master = 0; out_unlock: @@ -234,10 +234,10 @@ int drm_master_open(struct drm_file *file_priv) /* if there is no current master make this fd it, but do not create * any master object for render clients */ mutex_lock(&dev->master_mutex); - if (!file_priv->minor->master) + if (!dev->master) ret = drm_new_set_master(dev, file_priv); else - file_priv->master = drm_master_get(file_priv->minor->master); + file_priv->master = drm_master_get(dev->master); mutex_unlock(&dev->master_mutex); return ret; @@ -271,11 +271,11 @@ void drm_master_release(struct drm_file *file_priv) mutex_unlock(&dev->struct_mutex); } - if (file_priv->minor->master == file_priv->master) { + if (dev->master == file_priv->master) { /* drop the reference held my the minor */ if (dev->driver->master_drop) dev->driver->master_drop(dev, file_priv, true); - drm_master_put(&file_priv->minor->master); + drm_master_put(&dev->master); } /* drop the master reference held by the file priv */ diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 9b34158c0f77..c3a12cd8bd0d 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -51,7 +51,7 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, */ if (!entry->map || map->type != entry->map->type || - entry->master != dev->primary->master) + entry->master != dev->master) continue; switch (map->type) { case _DRM_SHM: @@ -245,12 +245,12 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, map->offset = (unsigned long)map->handle; if (map->flags & _DRM_CONTAINS_LOCK) { /* Prevent a 2nd X Server from creating a 2nd lock */ - if (dev->primary->master->lock.hw_lock != NULL) { + if (dev->master->lock.hw_lock != NULL) { vfree(map->handle); kfree(map); return -EBUSY; } - dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */ + dev->sigdata.lock = dev->master->lock.hw_lock = map->handle; /* Pointer to lock */ } break; case _DRM_AGP: { @@ -356,7 +356,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, mutex_unlock(&dev->struct_mutex); if (!(map->flags & _DRM_DRIVER)) - list->master = dev->primary->master; + list->master = dev->master; *maplist = list; return 0; } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0bac5246e5a7..0a06f9120b5a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -464,7 +464,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) /* Sometimes user space wants everything disabled, so don't steal the * display if there's a master. */ - if (dev->primary->master) + if (READ_ONCE(dev->master)) return false; drm_for_each_crtc(crtc, dev) { diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 0090d5987801..24c80dd13837 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c @@ -50,9 +50,12 @@ int drm_name_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_minor *minor = node->minor; struct drm_device *dev = minor->dev; - struct drm_master *master = minor->master; + struct drm_master *master; + + mutex_lock(&dev->master_mutex); + master = dev->master; if (!master) - return 0; + goto out_unlock; if (master->unique) { seq_printf(m, "%s %s %s\n", @@ -62,6 +65,9 @@ int drm_name_info(struct seq_file *m, void *data) seq_printf(m, "%s %s\n", dev->driver->name, dev_name(dev->dev)); } +out_unlock: + mutex_unlock(&dev->master_mutex); + return 0; } diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 0fb8f9e73486..ae0a4d39deec 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c @@ -334,7 +334,7 @@ void drm_legacy_lock_release(struct drm_device *dev, struct file *filp) struct drm_file *file_priv = filp->private_data; /* if the master has gone away we can't do anything with the lock */ - if (!file_priv->minor->master) + if (!dev->master) return; if (drm_legacy_i_have_hw_lock(dev, file_priv)) { diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 93ad8a5704d1..03defda77766 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c @@ -316,7 +316,7 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, struct sis_file_private *file_priv = file->driver_priv; struct sis_memblock *entry, *next; - if (!(file->minor->master && file->master->lock.hw_lock)) + if (!(dev->master && file->master->lock.hw_lock)) return; drm_legacy_idlelock_take(&file->master->lock); diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c index 4f20742e7788..a04ef1c992d9 100644 --- a/drivers/gpu/drm/via/via_mm.c +++ b/drivers/gpu/drm/via/via_mm.c @@ -208,7 +208,7 @@ void via_reclaim_buffers_locked(struct drm_device *dev, struct via_file_private *file_priv = file->driver_priv; struct via_memblock *entry, *next; - if (!(file->minor->master && file->master->lock.hw_lock)) + if (!(dev->master && file->master->lock.hw_lock)) return; drm_legacy_idlelock_take(&file->master->lock); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index e8788d7b29dc..62e0e70cb5a2 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -336,7 +336,7 @@ struct drm_file { void *driver_priv; struct drm_master *master; /* master this node is currently associated with - N.B. not always minor->master */ + N.B. not always dev->master */ /** * fbs - List of framebuffers associated with this file. * @@ -708,9 +708,6 @@ struct drm_minor { struct list_head debugfs_list; struct mutex debugfs_lock; /* Protects debugfs_list. */ - - /* currently active master for this node. Protected by master_mutex */ - struct drm_master *master; }; @@ -759,6 +756,10 @@ struct drm_device { struct drm_minor *control; /**< Control node */ struct drm_minor *primary; /**< Primary node */ struct drm_minor *render; /**< Render node */ + + /* currently active master for this device. Protected by master_mutex */ + struct drm_master *master; + atomic_t unplugged; /**< Flag whether dev is dead */ struct inode *anon_inode; /**< inode for private address-space */ char *unique; /**< unique name of the device */
There can only be one current master, and it's for the overall device. Render/control minors don't support master-based auth at all. This simplifies the master logic a lot, at least in my eyes: All these additional pointer chases are just confusing. While doing the conversion I spotted some locking fail: - drm_lock/drm_auth check dev->master without holding the master_mutex. This is fallout from commit c996fd0b956450563454e7ccc97a82ca31f9d043 Author: Thomas Hellstrom <thellstrom@vmware.com> Date: Tue Feb 25 19:57:44 2014 +0100 drm: Protect the master management with a drm_device::master_mutex v3 but I honestly don't care one bit about those old legacy drivers using this. - debugfs name info should just grab master_mutex. - And the fbdev helper looked at it to figure out whether someone is using KMS. We just need a consistent value, so READ_ONCE. Aside: We should probably check if anyone has opened a control node too, but I guess current userspace doesn't really do that yet. v2: Balance locking, reported by Julia. Cc: Julia Lawall <julia.lawall@lip6.fr> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- drivers/gpu/drm/drm_auth.c | 26 +++++++++++++------------- drivers/gpu/drm/drm_bufs.c | 8 ++++---- drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/gpu/drm/drm_info.c | 10 ++++++++-- drivers/gpu/drm/drm_lock.c | 2 +- drivers/gpu/drm/sis/sis_mm.c | 2 +- drivers/gpu/drm/via/via_mm.c | 2 +- include/drm/drmP.h | 9 +++++---- 8 files changed, 34 insertions(+), 27 deletions(-)