diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2009-12-02 13:15:25 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-12-03 17:55:46 -0500 |
commit | 862302ffe422378a5213f558fc5cdf62c37050a9 (patch) | |
tree | 13557874eb479023e5a64f12990416045ea60818 /drivers/gpu/drm/drm_stub.c | |
parent | 9340d8cfeacd16cef1cbe94527f7baaed7640669 (diff) |
drm: Add support for drm master_[set|drop] callbacks.
The vmwgfx driver has a per master rw lock around TTM, to guarantee
mutual exclusion when needed.
This is typically when all evictable buffers are evicted due to
1) vt switch
2) master switch
3) suspend / resume.
In the multi-master case, on master switch the new master takes the
previously active master lock in write mode, and then evicts all
buffers. Any clients to previous masters will then block on that lock
when trying to validate a buffer. fbdev also acts as a virtual master
wrt this.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_stub.c')
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index adb864dfef3e..2c1b52847e9e 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -174,6 +174,8 @@ void drm_master_put(struct drm_master **master) | |||
174 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, | 174 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, |
175 | struct drm_file *file_priv) | 175 | struct drm_file *file_priv) |
176 | { | 176 | { |
177 | int ret = 0; | ||
178 | |||
177 | if (file_priv->is_master) | 179 | if (file_priv->is_master) |
178 | return 0; | 180 | return 0; |
179 | 181 | ||
@@ -188,6 +190,13 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, | |||
188 | mutex_lock(&dev->struct_mutex); | 190 | mutex_lock(&dev->struct_mutex); |
189 | file_priv->minor->master = drm_master_get(file_priv->master); | 191 | file_priv->minor->master = drm_master_get(file_priv->master); |
190 | file_priv->is_master = 1; | 192 | file_priv->is_master = 1; |
193 | if (dev->driver->master_set) { | ||
194 | ret = dev->driver->master_set(dev, file_priv, false); | ||
195 | if (unlikely(ret != 0)) { | ||
196 | file_priv->is_master = 0; | ||
197 | drm_master_put(&file_priv->minor->master); | ||
198 | } | ||
199 | } | ||
191 | mutex_unlock(&dev->struct_mutex); | 200 | mutex_unlock(&dev->struct_mutex); |
192 | } | 201 | } |
193 | 202 | ||
@@ -204,6 +213,8 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | |||
204 | return -EINVAL; | 213 | return -EINVAL; |
205 | 214 | ||
206 | mutex_lock(&dev->struct_mutex); | 215 | mutex_lock(&dev->struct_mutex); |
216 | if (dev->driver->master_drop) | ||
217 | dev->driver->master_drop(dev, file_priv, false); | ||
207 | drm_master_put(&file_priv->minor->master); | 218 | drm_master_put(&file_priv->minor->master); |
208 | file_priv->is_master = 0; | 219 | file_priv->is_master = 0; |
209 | mutex_unlock(&dev->struct_mutex); | 220 | mutex_unlock(&dev->struct_mutex); |