From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thomas Hellstrom Subject: Re: [PATCH 2/2] drm: set dev_mapping before calling drm_open_helper Date: Tue, 30 Oct 2012 14:54:21 +0100 Message-ID: <508FDC0D.1020002@vmware.com> References: <1351532101-8523-1-git-send-email-ihadzic@research.bell-labs.com> <1351532101-8523-2-git-send-email-ihadzic@research.bell-labs.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from smtp-outbound-1.vmware.com (smtp-outbound-1.vmware.com [208.91.2.12]) by gabe.freedesktop.org (Postfix) with ESMTP id 8C2A89E7C6 for ; Tue, 30 Oct 2012 06:54:25 -0700 (PDT) In-Reply-To: <1351532101-8523-2-git-send-email-ihadzic@research.bell-labs.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: Ilija Hadzic Cc: stable@vger.kernel.org, dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org Reviewed-by: Thomas Hellstrom On 10/29/2012 06:35 PM, Ilija Hadzic wrote: > Some drivers (specifically vmwgfx) look at dev_mapping > in their open hook, so we have to set dev->dev_mapping > earlier in the process. > > Reference: > http://lists.freedesktop.org/archives/dri-devel/2012-October/029420.html > > Signed-off-by: Ilija Hadzic > Reported-by: Thomas Hellstrom > Cc: stable@vger.kernel.org > --- > drivers/gpu/drm/drm_fops.c | 47 +++++++++++++++++++++++++++++----------------- > 1 file changed, 30 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c > index af68eca..133b413 100644 > --- a/drivers/gpu/drm/drm_fops.c > +++ b/drivers/gpu/drm/drm_fops.c > @@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp) > int minor_id = iminor(inode); > struct drm_minor *minor; > int retcode = 0; > + int need_setup = 0; > + struct address_space *old_mapping; > > minor = idr_find(&drm_minors_idr, minor_id); > if (!minor) > @@ -132,26 +134,37 @@ int drm_open(struct inode *inode, struct file *filp) > if (drm_device_is_unplugged(dev)) > return -ENODEV; > > + if (!dev->open_count++) > + need_setup = 1; > + mutex_lock(&dev->struct_mutex); > + old_mapping = dev->dev_mapping; > + if (old_mapping == NULL) > + dev->dev_mapping = &inode->i_data; > + /* ihold ensures nobody can remove inode with our i_data */ > + ihold(container_of(dev->dev_mapping, struct inode, i_data)); > + inode->i_mapping = dev->dev_mapping; > + filp->f_mapping = dev->dev_mapping; > + mutex_unlock(&dev->struct_mutex); > + > retcode = drm_open_helper(inode, filp, dev); > - if (!retcode) { > - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); > - if (!dev->open_count++) { > - retcode = drm_setup(dev); > - if (retcode) > - dev->open_count--; > - } > - } > - if (!retcode) { > - mutex_lock(&dev->struct_mutex); > - if (dev->dev_mapping == NULL) > - dev->dev_mapping = &inode->i_data; > - /* ihold ensures nobody can remove inode with our i_data */ > - ihold(container_of(dev->dev_mapping, struct inode, i_data)); > - inode->i_mapping = dev->dev_mapping; > - filp->f_mapping = dev->dev_mapping; > - mutex_unlock(&dev->struct_mutex); > + if (retcode) > + goto err_undo; > + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); > + if (need_setup) { > + retcode = drm_setup(dev); > + if (retcode) > + goto err_undo; > } > + return 0; > > +err_undo: > + mutex_lock(&dev->struct_mutex); > + filp->f_mapping = old_mapping; > + inode->i_mapping = old_mapping; > + iput(container_of(dev->dev_mapping, struct inode, i_data)); > + dev->dev_mapping = old_mapping; > + mutex_unlock(&dev->struct_mutex); > + dev->open_count--; > return retcode; > } > EXPORT_SYMBOL(drm_open);