From 8e083c522e73f27af7e97e0d202f56f0323abe81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Sat, 26 May 2007 04:35:54 +1000 Subject: drm: make sure the drawable code doesn't call malloc(0). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michel Dänzer Signed-off-by: Dave Airlie --- linux-core/drm_drawable.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 0817e321..b540a0e7 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -172,38 +172,49 @@ int drm_rmdraw(DRM_IOCTL_ARGS) bitfield_length = idx + 1; - if (idx != id / (8 * sizeof(*bitfield))) - bitfield = drm_alloc(bitfield_length * - sizeof(*bitfield), DRM_MEM_BUFS); + bitfield = NULL; - if (!bitfield && bitfield_length) { - bitfield = dev->drw_bitfield; - bitfield_length = dev->drw_bitfield_length; + if (bitfield_length) { + if (bitfield_length != dev->drw_bitfield_length) + bitfield = drm_alloc(bitfield_length * + sizeof(*bitfield), + DRM_MEM_BUFS); + + if (!bitfield) { + bitfield = dev->drw_bitfield; + bitfield_length = dev->drw_bitfield_length; + } } } if (bitfield != dev->drw_bitfield) { info_length = 8 * sizeof(*bitfield) * bitfield_length; - info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS); + if (info_length) { + info = drm_alloc(info_length * sizeof(*info), + DRM_MEM_BUFS); - if (!info && info_length) { - info = dev->drw_info; - info_length = dev->drw_info_length; - } + if (!info) { + info = dev->drw_info; + info_length = dev->drw_info_length; + } + } else + info = NULL; spin_lock_irqsave(&dev->drw_lock, irqflags); - memcpy(bitfield, dev->drw_bitfield, bitfield_length * - sizeof(*bitfield)); + if (bitfield) + memcpy(bitfield, dev->drw_bitfield, bitfield_length * + sizeof(*bitfield)); drm_free(dev->drw_bitfield, sizeof(*bitfield) * dev->drw_bitfield_length, DRM_MEM_BUFS); dev->drw_bitfield = bitfield; dev->drw_bitfield_length = bitfield_length; if (info != dev->drw_info) { - memcpy(info, dev->drw_info, info_length * - sizeof(*info)); + if (info) + memcpy(info, dev->drw_info, info_length * + sizeof(*info)); drm_free(dev->drw_info, sizeof(*info) * dev->drw_info_length, DRM_MEM_BUFS); dev->drw_info = info; -- cgit v1.2.3 From f64674743a49c242e4f24cbb7599c1c21c035a4f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 May 2007 07:26:52 +1000 Subject: drm: convert drawable handling to use Linux idr This cleans this code up a lot and uses the generic Linux idr which is designed for this. Signed-off-by: Dave Airlie --- linux-core/drm_drawable.c | 224 +++++++++------------------------------------- 1 file changed, 42 insertions(+), 182 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index b540a0e7..d599430b 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -44,82 +44,38 @@ int drm_adddraw(DRM_IOCTL_ARGS) { DRM_DEVICE; unsigned long irqflags; - int i, j; - u32 *bitfield = dev->drw_bitfield; - unsigned int bitfield_length = dev->drw_bitfield_length; - drm_drawable_info_t **info = dev->drw_info; - unsigned int info_length = dev->drw_info_length; + struct drm_drawable_list *draw_info; drm_draw_t draw; - - for (i = 0, j = 0; i < bitfield_length; i++) { - if (bitfield[i] == ~0) - continue; - - for (; j < 8 * sizeof(*bitfield); j++) - if (!(bitfield[i] & (1 << j))) - goto done; - } -done: - - if (i == bitfield_length) { - bitfield_length++; - - bitfield = drm_alloc(bitfield_length * sizeof(*bitfield), - DRM_MEM_BUFS); - - if (!bitfield) { - DRM_ERROR("Failed to allocate new drawable bitfield\n"); - return DRM_ERR(ENOMEM); - } - - if (8 * sizeof(*bitfield) * bitfield_length > info_length) { - info_length += 8 * sizeof(*bitfield); - - info = drm_alloc(info_length * sizeof(*info), - DRM_MEM_BUFS); - - if (!info) { - DRM_ERROR("Failed to allocate new drawable info" - " array\n"); - - drm_free(bitfield, - bitfield_length * sizeof(*bitfield), - DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); - } - } - - bitfield[i] = 0; + int new_id = 0; + int ret; + + draw_info = drm_calloc(1, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + if (!draw_info) + return -ENOMEM; + +again: + if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { + DRM_ERROR("Out of memory expanding drawable idr\n"); + drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + return -ENOMEM; } - draw.handle = i * 8 * sizeof(*bitfield) + j + 1; - DRM_DEBUG("%d\n", draw.handle); - spin_lock_irqsave(&dev->drw_lock, irqflags); - - bitfield[i] |= 1 << j; - info[draw.handle - 1] = NULL; - - if (bitfield != dev->drw_bitfield) { - memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length * - sizeof(*bitfield)); - drm_free(dev->drw_bitfield, sizeof(*bitfield) * - dev->drw_bitfield_length, DRM_MEM_BUFS); - dev->drw_bitfield = bitfield; - dev->drw_bitfield_length = bitfield_length; + ret = idr_get_new_above(&dev->drw_idr, draw_info, 1, &new_id); + if (ret == -EAGAIN) { + spin_unlock_irqrestore(&dev->drw_lock, irqflags); + goto again; } - if (info != dev->drw_info) { - memcpy(info, dev->drw_info, dev->drw_info_length * - sizeof(*info)); - drm_free(dev->drw_info, sizeof(*info) * dev->drw_info_length, - DRM_MEM_BUFS); - dev->drw_info = info; - dev->drw_info_length = info_length; - } + list_add(&draw_info->head, &dev->drwlist); spin_unlock_irqrestore(&dev->drw_lock, irqflags); + draw_info->id = new_id; + draw.handle = new_id; + + DRM_DEBUG("%d\n", draw.handle); + DRM_COPY_TO_USER_IOCTL((drm_draw_t __user *)data, draw, sizeof(draw)); return 0; @@ -132,98 +88,25 @@ int drm_rmdraw(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_draw_t draw; - int id, idx; - unsigned int shift; unsigned long irqflags; - u32 *bitfield = dev->drw_bitfield; - unsigned int bitfield_length = dev->drw_bitfield_length; - drm_drawable_info_t **info = dev->drw_info; - unsigned int info_length = dev->drw_info_length; + struct drm_drawable_list *draw_info; DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, sizeof(draw)); - id = draw.handle - 1; - idx = id / (8 * sizeof(*bitfield)); - shift = id % (8 * sizeof(*bitfield)); - - if (idx < 0 || idx >= bitfield_length || - !(bitfield[idx] & (1 << shift))) { + draw_info = idr_find(&dev->drw_idr, draw.handle); + if (!draw_info) { DRM_DEBUG("No such drawable %d\n", draw.handle); - return 0; + return -EINVAL; } spin_lock_irqsave(&dev->drw_lock, irqflags); - bitfield[idx] &= ~(1 << shift); + list_del(&draw_info->head); + idr_remove(&dev->drw_idr, draw.handle); + drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - if (info[id]) { - drm_free(info[id]->rects, info[id]->num_rects * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - drm_free(info[id], sizeof(**info), DRM_MEM_BUFS); - } - - /* Can we shrink the arrays? */ - if (idx == bitfield_length - 1) { - while (idx >= 0 && !bitfield[idx]) - --idx; - - bitfield_length = idx + 1; - - bitfield = NULL; - - if (bitfield_length) { - if (bitfield_length != dev->drw_bitfield_length) - bitfield = drm_alloc(bitfield_length * - sizeof(*bitfield), - DRM_MEM_BUFS); - - if (!bitfield) { - bitfield = dev->drw_bitfield; - bitfield_length = dev->drw_bitfield_length; - } - } - } - - if (bitfield != dev->drw_bitfield) { - info_length = 8 * sizeof(*bitfield) * bitfield_length; - - if (info_length) { - info = drm_alloc(info_length * sizeof(*info), - DRM_MEM_BUFS); - - if (!info) { - info = dev->drw_info; - info_length = dev->drw_info_length; - } - } else - info = NULL; - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - if (bitfield) - memcpy(bitfield, dev->drw_bitfield, bitfield_length * - sizeof(*bitfield)); - drm_free(dev->drw_bitfield, sizeof(*bitfield) * - dev->drw_bitfield_length, DRM_MEM_BUFS); - dev->drw_bitfield = bitfield; - dev->drw_bitfield_length = bitfield_length; - - if (info != dev->drw_info) { - if (info) - memcpy(info, dev->drw_info, info_length * - sizeof(*info)); - drm_free(dev->drw_info, sizeof(*info) * - dev->drw_info_length, DRM_MEM_BUFS); - dev->drw_info = info; - dev->drw_info_length = info_length; - } - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - } - DRM_DEBUG("%d\n", draw.handle); return 0; } @@ -231,36 +114,22 @@ int drm_rmdraw(DRM_IOCTL_ARGS) int drm_update_drawable_info(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_update_draw_t update; - unsigned int id, idx, shift, bitfield_length = dev->drw_bitfield_length; - u32 *bitfield = dev->drw_bitfield; unsigned long irqflags; drm_drawable_info_t *info; drm_clip_rect_t *rects; + struct drm_drawable_list *draw_info; int err; DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data, sizeof(update)); - id = update.handle - 1; - idx = id / (8 * sizeof(*bitfield)); - shift = id % (8 * sizeof(*bitfield)); - - if (idx < 0 || idx >= bitfield_length || - !(bitfield[idx] & (1 << shift))) { + draw_info = idr_find(&dev->drw_idr, update.handle); + if (!draw_info) { DRM_ERROR("No such drawable %d\n", update.handle); return DRM_ERR(EINVAL); } - info = dev->drw_info[id]; - - if (!info) { - info = drm_calloc(1, sizeof(drm_drawable_info_t), DRM_MEM_BUFS); - - if (!info) { - DRM_ERROR("Failed to allocate drawable info memory\n"); - return DRM_ERR(ENOMEM); - } - } + info = &draw_info->info; switch (update.type) { case DRM_DRAWABLE_CLIPRECTS: @@ -295,12 +164,11 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) { info->rects = rects; info->num_rects = update.num; - dev->drw_info[id] = info; spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("Updated %d cliprects for drawable %d\n", - info->num_rects, id); + info->num_rects, update.handle); break; default: DRM_ERROR("Invalid update type %d\n", update.type); @@ -310,11 +178,9 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) { return 0; error: - if (!dev->drw_info[id]) - drm_free(info, sizeof(*info), DRM_MEM_BUFS); - else if (rects != dev->drw_info[id]->rects) - drm_free(rects, update.num * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + if (rects != info->rects) + drm_free(rects, update.num * sizeof(drm_clip_rect_t), + DRM_MEM_BUFS); return err; } @@ -323,19 +189,13 @@ error: * Caller must hold the drawable spinlock! */ drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { - u32 *bitfield = dev->drw_bitfield; - unsigned int idx, shift; - - id--; - idx = id / (8 * sizeof(*bitfield)); - shift = id % (8 * sizeof(*bitfield)); - - if (idx < 0 || idx >= dev->drw_bitfield_length || - !(bitfield[idx] & (1 << shift))) { + struct drm_drawable_list *draw_info; + draw_info = idr_find(&dev->drw_idr, id); + if (!draw_info) { DRM_DEBUG("No such drawable %d\n", id); return NULL; } - return dev->drw_info[id]; + return &draw_info->info; } EXPORT_SYMBOL(drm_get_drawable_info); -- cgit v1.2.3 From 280083d4a2a12a1ff6dc1b068553a4ae8960200c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 10 Jun 2007 15:40:10 +1000 Subject: use krh's idr mods to remove lists from idr code --- linux-core/drm_drawable.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index d599430b..eb44a189 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -67,11 +67,8 @@ again: goto again; } - list_add(&draw_info->head, &dev->drwlist); - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - draw_info->id = new_id; draw.handle = new_id; DRM_DEBUG("%d\n", draw.handle); @@ -102,7 +99,6 @@ int drm_rmdraw(DRM_IOCTL_ARGS) spin_lock_irqsave(&dev->drw_lock, irqflags); - list_del(&draw_info->head); idr_remove(&dev->drw_idr, draw.handle); drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); @@ -199,3 +195,18 @@ drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) return &draw_info->info; } EXPORT_SYMBOL(drm_get_drawable_info); + +static int drm_drawable_free(int idr, void *p, void *data) +{ + struct drm_drawable_list *drw_entry = p; + drm_free(drw_entry->info.rects, drw_entry->info.num_rects * + sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + drm_free(drw_entry, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + return 0; +} + +void drm_drawable_free_all(drm_device_t *dev) +{ + idr_for_each(&dev->drw_idr, drm_drawable_free, NULL); + idr_remove_all(&dev->drw_idr); +} -- cgit v1.2.3 From b323ab52aa9ccbfb06dd723ece361a5242d067b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 28 Jun 2007 14:45:26 -0400 Subject: Drop drm_drawable_list and add drm_drawable_info directly to the idr. --- linux-core/drm_drawable.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index eb44a189..74f0bb5d 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -44,19 +44,19 @@ int drm_adddraw(DRM_IOCTL_ARGS) { DRM_DEVICE; unsigned long irqflags; - struct drm_drawable_list *draw_info; + struct drm_drawable_info *draw_info; drm_draw_t draw; int new_id = 0; int ret; - draw_info = drm_calloc(1, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + draw_info = drm_calloc(1, sizeof(*draw_info), DRM_MEM_BUFS); if (!draw_info) return -ENOMEM; again: if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { DRM_ERROR("Out of memory expanding drawable idr\n"); - drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); return -ENOMEM; } @@ -86,7 +86,7 @@ int drm_rmdraw(DRM_IOCTL_ARGS) DRM_DEVICE; drm_draw_t draw; unsigned long irqflags; - struct drm_drawable_list *draw_info; + struct drm_drawable_info *draw_info; DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, sizeof(draw)); @@ -100,33 +100,31 @@ int drm_rmdraw(DRM_IOCTL_ARGS) spin_lock_irqsave(&dev->drw_lock, irqflags); idr_remove(&dev->drw_idr, draw.handle); - drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("%d\n", draw.handle); return 0; } -int drm_update_drawable_info(DRM_IOCTL_ARGS) { +int drm_update_drawable_info(DRM_IOCTL_ARGS) +{ DRM_DEVICE; drm_update_draw_t update; unsigned long irqflags; - drm_drawable_info_t *info; drm_clip_rect_t *rects; - struct drm_drawable_list *draw_info; + struct drm_drawable_info *info; int err; DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data, sizeof(update)); - draw_info = idr_find(&dev->drw_idr, update.handle); - if (!draw_info) { + info = idr_find(&dev->drw_idr, update.handle); + if (!info) { DRM_ERROR("No such drawable %d\n", update.handle); return DRM_ERR(EINVAL); } - info = &draw_info->info; - switch (update.type) { case DRM_DRAWABLE_CLIPRECTS: if (update.num != info->num_rects) { @@ -184,24 +182,27 @@ error: /** * Caller must hold the drawable spinlock! */ -drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { - struct drm_drawable_list *draw_info; - draw_info = idr_find(&dev->drw_idr, id); - if (!draw_info) { +drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) +{ + struct drm_drawable_info *info; + + info = idr_find(&dev->drw_idr, id); + if (!info) { DRM_DEBUG("No such drawable %d\n", id); return NULL; } - return &draw_info->info; + return info; } EXPORT_SYMBOL(drm_get_drawable_info); static int drm_drawable_free(int idr, void *p, void *data) { - struct drm_drawable_list *drw_entry = p; - drm_free(drw_entry->info.rects, drw_entry->info.num_rects * + struct drm_drawable_info *info = p; + + drm_free(info->rects, info->num_rects * sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - drm_free(drw_entry, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); return 0; } -- cgit v1.2.3 From 8d96ba9805316b29e948d7594344feebb17042f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 3 Jul 2007 11:41:44 +0200 Subject: Restore pre-idr semantics for drawable information. There's a difference between a drawable ID not having valid drawable information and not being allocated at all. Not making the distinction would break i915 DRM swap scheduling with older X servers that don't push drawable cliprect information to the DRM. --- linux-core/drm_drawable.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 74f0bb5d..7657e954 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -37,6 +37,8 @@ #include "drmP.h" +#define NO_DRW_INFO (void*)1 + /** * Allocate drawable ID and memory to store information about it. */ @@ -44,24 +46,18 @@ int drm_adddraw(DRM_IOCTL_ARGS) { DRM_DEVICE; unsigned long irqflags; - struct drm_drawable_info *draw_info; drm_draw_t draw; int new_id = 0; int ret; - draw_info = drm_calloc(1, sizeof(*draw_info), DRM_MEM_BUFS); - if (!draw_info) - return -ENOMEM; - again: if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { DRM_ERROR("Out of memory expanding drawable idr\n"); - drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); return -ENOMEM; } spin_lock_irqsave(&dev->drw_lock, irqflags); - ret = idr_get_new_above(&dev->drw_idr, draw_info, 1, &new_id); + ret = idr_get_new_above(&dev->drw_idr, NO_DRW_INFO, 1, &new_id); if (ret == -EAGAIN) { spin_unlock_irqrestore(&dev->drw_lock, irqflags); goto again; @@ -86,21 +82,16 @@ int drm_rmdraw(DRM_IOCTL_ARGS) DRM_DEVICE; drm_draw_t draw; unsigned long irqflags; - struct drm_drawable_info *draw_info; DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, sizeof(draw)); - draw_info = idr_find(&dev->drw_idr, draw.handle); - if (!draw_info) { - DRM_DEBUG("No such drawable %d\n", draw.handle); - return -EINVAL; - } - spin_lock_irqsave(&dev->drw_lock, irqflags); + drm_free(drm_get_drawable_info(dev, draw.handle), + sizeof(struct drm_drawable_info), DRM_MEM_BUFS); + idr_remove(&dev->drw_idr, draw.handle); - drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("%d\n", draw.handle); @@ -125,6 +116,13 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } + if (info == NO_DRW_INFO) { + info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); + if (!info) + return -ENOMEM; + idr_replace(&dev->drw_idr, info, update.handle); + } + switch (update.type) { case DRM_DRAWABLE_CLIPRECTS: if (update.num != info->num_rects) { @@ -187,11 +185,17 @@ drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) struct drm_drawable_info *info; info = idr_find(&dev->drw_idr, id); + if (!info) { DRM_DEBUG("No such drawable %d\n", id); return NULL; } + if (info == NO_DRW_INFO) { + DRM_DEBUG("No information for drawable %d\n", id); + return NULL; + } + return info; } EXPORT_SYMBOL(drm_get_drawable_info); @@ -200,9 +204,12 @@ static int drm_drawable_free(int idr, void *p, void *data) { struct drm_drawable_info *info = p; - drm_free(info->rects, info->num_rects * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); + if (info != NO_DRW_INFO) { + drm_free(info->rects, info->num_rects * + sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + drm_free(info, sizeof(*info), DRM_MEM_BUFS); + } + return 0; } -- cgit v1.2.3 From ea832a8e555c9e1f90830b55cbd970d0eca0e2cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 3 Jul 2007 12:15:15 +0200 Subject: Simplification for previous commit. Dave Airlie pointed out on IRC that idr_replace lets us know if the ID hasn't been allocated, so we don't need a special pointer value for allocated IDs that don't have valid information yet. --- linux-core/drm_drawable.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 7657e954..57b62ca4 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -37,8 +37,6 @@ #include "drmP.h" -#define NO_DRW_INFO (void*)1 - /** * Allocate drawable ID and memory to store information about it. */ @@ -57,7 +55,7 @@ again: } spin_lock_irqsave(&dev->drw_lock, irqflags); - ret = idr_get_new_above(&dev->drw_idr, NO_DRW_INFO, 1, &new_id); + ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id); if (ret == -EAGAIN) { spin_unlock_irqrestore(&dev->drw_lock, irqflags); goto again; @@ -112,15 +110,15 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) info = idr_find(&dev->drw_idr, update.handle); if (!info) { - DRM_ERROR("No such drawable %d\n", update.handle); - return DRM_ERR(EINVAL); - } - - if (info == NO_DRW_INFO) { info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); if (!info) return -ENOMEM; - idr_replace(&dev->drw_idr, info, update.handle); + if (idr_replace(&dev->drw_idr, info, update.handle) == + (void*)-ENOENT) { + DRM_ERROR("No such drawable %d\n", update.handle); + drm_free(info, sizeof(*info), DRM_MEM_BUFS); + return -EINVAL; + } } switch (update.type) { @@ -182,21 +180,7 @@ error: */ drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { - struct drm_drawable_info *info; - - info = idr_find(&dev->drw_idr, id); - - if (!info) { - DRM_DEBUG("No such drawable %d\n", id); - return NULL; - } - - if (info == NO_DRW_INFO) { - DRM_DEBUG("No information for drawable %d\n", id); - return NULL; - } - - return info; + return idr_find(&dev->drw_idr, id); } EXPORT_SYMBOL(drm_get_drawable_info); @@ -204,7 +188,7 @@ static int drm_drawable_free(int idr, void *p, void *data) { struct drm_drawable_info *info = p; - if (info != NO_DRW_INFO) { + if (info) { drm_free(info->rects, info->num_rects * sizeof(drm_clip_rect_t), DRM_MEM_BUFS); drm_free(info, sizeof(*info), DRM_MEM_BUFS); -- cgit v1.2.3 From d57b7f02d2e525e5600e5d77370d7ad2b4c9b265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 3 Jul 2007 10:41:48 -0400 Subject: Use idr_replace trick to eliminate struct drm_ctx_sarea_list. --- linux-core/drm_drawable.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux-core/drm_drawable.c') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 57b62ca4..7129980b 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -113,8 +113,7 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); if (!info) return -ENOMEM; - if (idr_replace(&dev->drw_idr, info, update.handle) == - (void*)-ENOENT) { + if (IS_ERR(idr_replace(&dev->drw_idr, info, update.handle))) { DRM_ERROR("No such drawable %d\n", update.handle); drm_free(info, sizeof(*info), DRM_MEM_BUFS); return -EINVAL; -- cgit v1.2.3