summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-03-20 04:56:14 +0300
committerDave Airlie <airlied@redhat.com>2009-03-29 12:31:37 +0400
commit955a23eb3cfc773e71b05bb7a0a0938a9e1b2568 (patch)
tree7a9124ddf103ef1f6337484bb5e5ae51c9c288a6
parentaf7ae351ad63a137ece86740dbe3f181d09d810f (diff)
downloadlinux-955a23eb3cfc773e71b05bb7a0a0938a9e1b2568.tar.xz
drm: Use a little stash on the stack to avoid kmalloc in most DRM ioctls.
The kmalloc was taking up about 1.5% of the CPU on an ioctl-heavy workload (x11perf -aa10text on 965). Initial results look like they have a corresponding improvement in performance for aa10text, but more numbers might not hurt. Thanks to ajax for pointing out this performance regression I'd introduced back in 2007. [airlied: well I introduced it sneakily inside Eric's patch] Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_drv.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c26ee0822a05..c4ada8b6295b 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -421,6 +421,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
drm_ioctl_t *func;
unsigned int nr = DRM_IOCTL_NR(cmd);
int retcode = -EINVAL;
+ char stack_kdata[128];
char *kdata = NULL;
atomic_inc(&dev->ioctl_count);
@@ -459,10 +460,14 @@ int drm_ioctl(struct inode *inode, struct file *filp,
retcode = -EACCES;
} else {
if (cmd & (IOC_IN | IOC_OUT)) {
- kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
- if (!kdata) {
- retcode = -ENOMEM;
- goto err_i1;
+ if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) {
+ kdata = stack_kdata;
+ } else {
+ kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+ if (!kdata) {
+ retcode = -ENOMEM;
+ goto err_i1;
+ }
}
}
@@ -483,7 +488,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
}
err_i1:
- if (kdata)
+ if (kdata != stack_kdata)
kfree(kdata);
atomic_dec(&dev->ioctl_count);
if (retcode)