aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i830
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-07-10 17:51:39 -0400
committerDave Airlie <airlied@redhat.com>2010-08-04 21:54:40 -0400
commit58374713c9dfb4d231f8c56cac089f6fbdedc2ec (patch)
tree9ba01c3990b5a8625437d13722595f5063f2d915 /drivers/gpu/drm/i830
parenta1e09b62592eb57e25f8d076ffa5b7bef18be812 (diff)
drm: kill BKL from common code
This restricts the use of the big kernel lock to the i830 and i810 device drivers. The three remaining users in common code (open, ioctl and release) get converted to a new mutex, the drm_global_mutex, making the locking stricter than the big kernel lock. This may have a performance impact, but only in those cases that currently don't use DRM_UNLOCKED flag in the ioctl list and would benefit from that anyway. The reason why i810 and i830 cannot use drm_global_mutex in their mmap functions is a lock-order inversion problem between the current use of the BKL and mmap_sem in these drivers. Since the BKL has release-on-sleep semantics, it's harmless but it would cause trouble if we replace the BKL with a mutex. Instead, these drivers get their own ioctl wrappers that take the BKL around every ioctl call and then set their own handlers as DRM_UNLOCKED. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: David Airlie <airlied@linux.ie> Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i830')
-rw-r--r--drivers/gpu/drm/i830/i830_dma.c42
-rw-r--r--drivers/gpu/drm/i830/i830_drv.c2
-rw-r--r--drivers/gpu/drm/i830/i830_drv.h1
3 files changed, 30 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c
index 7ee85ea507ce..5168862c9227 100644
--- a/drivers/gpu/drm/i830/i830_dma.c
+++ b/drivers/gpu/drm/i830/i830_dma.c
@@ -36,6 +36,7 @@
36#include "i830_drm.h" 36#include "i830_drm.h"
37#include "i830_drv.h" 37#include "i830_drv.h"
38#include <linux/interrupt.h> /* For task queue support */ 38#include <linux/interrupt.h> /* For task queue support */
39#include <linux/smp_lock.h>
39#include <linux/pagemap.h> 40#include <linux/pagemap.h>
40#include <linux/delay.h> 41#include <linux/delay.h>
41#include <linux/slab.h> 42#include <linux/slab.h>
@@ -1509,21 +1510,34 @@ int i830_driver_dma_quiescent(struct drm_device *dev)
1509 return 0; 1510 return 0;
1510} 1511}
1511 1512
1513/*
1514 * call the drm_ioctl under the big kernel lock because
1515 * to lock against the i830_mmap_buffers function.
1516 */
1517long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1518{
1519 int ret;
1520 lock_kernel();
1521 ret = drm_ioctl(file, cmd, arg);
1522 unlock_kernel();
1523 return ret;
1524}
1525
1512struct drm_ioctl_desc i830_ioctls[] = { 1526struct drm_ioctl_desc i830_ioctls[] = {
1513 DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 1527 DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
1514 DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH), 1528 DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
1515 DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH), 1529 DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
1516 DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH), 1530 DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
1517 DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH), 1531 DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED),
1518 DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH), 1532 DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED),
1519 DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH), 1533 DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
1520 DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH), 1534 DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED),
1521 DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH), 1535 DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED),
1522 DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH), 1536 DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
1523 DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH), 1537 DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED),
1524 DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH), 1538 DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED),
1525 DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH), 1539 DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED),
1526 DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH) 1540 DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED),
1527}; 1541};
1528 1542
1529int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); 1543int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c
index 44f990bed8f4..a5c66aa82f0c 100644
--- a/drivers/gpu/drm/i830/i830_drv.c
+++ b/drivers/gpu/drm/i830/i830_drv.c
@@ -70,7 +70,7 @@ static struct drm_driver driver = {
70 .owner = THIS_MODULE, 70 .owner = THIS_MODULE,
71 .open = drm_open, 71 .open = drm_open,
72 .release = drm_release, 72 .release = drm_release,
73 .unlocked_ioctl = drm_ioctl, 73 .unlocked_ioctl = i830_ioctl,
74 .mmap = drm_mmap, 74 .mmap = drm_mmap,
75 .poll = drm_poll, 75 .poll = drm_poll,
76 .fasync = drm_fasync, 76 .fasync = drm_fasync,
diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h
index ecfd25a35da3..0df1c720560b 100644
--- a/drivers/gpu/drm/i830/i830_drv.h
+++ b/drivers/gpu/drm/i830/i830_drv.h
@@ -122,6 +122,7 @@ typedef struct drm_i830_private {
122 122
123} drm_i830_private_t; 123} drm_i830_private_t;
124 124
125long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
125extern struct drm_ioctl_desc i830_ioctls[]; 126extern struct drm_ioctl_desc i830_ioctls[];
126extern int i830_max_ioctl; 127extern int i830_max_ioctl;
127 128