Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'drm-patches' of ssh://master.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-patches' of ssh://master.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm: convert drawable code to using idr
drm: convert drm context code to use Linux idr

+94 -313
+5 -6
drivers/char/drm/drmP.h
··· 75 75 #include <asm/pgalloc.h> 76 76 #include "drm.h" 77 77 78 + #include <linux/idr.h> 79 + 78 80 #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE))) 79 81 #define __OS_HAS_MTRR (defined(CONFIG_MTRR)) 80 82 ··· 678 676 int ctx_count; /**< Number of context handles */ 679 677 struct mutex ctxlist_mutex; /**< For ctxlist */ 680 678 681 - struct drm_map **context_sareas; /**< per-context SAREA's */ 682 - int max_context; 679 + struct idr ctx_idr; 683 680 684 681 struct list_head vmalist; /**< List of vmas (for debugging) */ 685 682 struct drm_lock_data lock; /**< Information on hardware lock */ ··· 751 750 /** \name Drawable information */ 752 751 /*@{ */ 753 752 spinlock_t drw_lock; 754 - unsigned int drw_bitfield_length; 755 - u32 *drw_bitfield; 756 - unsigned int drw_info_length; 757 - struct drm_drawable_info **drw_info; 753 + struct idr drw_idr; 758 754 /*@} */ 759 755 }; 760 756 ··· 901 903 unsigned int cmd, unsigned long arg); 902 904 extern struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, 903 905 drm_drawable_t id); 906 + extern void drm_drawable_free_all(struct drm_device *dev); 904 907 905 908 /* Authentication IOCTL support (drm_auth.h) */ 906 909 extern int drm_getmagic(struct inode *inode, struct file *filp,
+30 -101
drivers/char/drm/drm_context.c
··· 53 53 * \param ctx_handle context handle. 54 54 * 55 55 * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry 56 - * in drm_device::context_sareas, while holding the drm_device::struct_mutex 56 + * in drm_device::ctx_idr, while holding the drm_device::struct_mutex 57 57 * lock. 58 58 */ 59 59 void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) 60 60 { 61 - if (ctx_handle < 0) 62 - goto failed; 63 - if (!dev->ctx_bitmap) 64 - goto failed; 65 - 66 - if (ctx_handle < DRM_MAX_CTXBITMAP) { 67 - mutex_lock(&dev->struct_mutex); 68 - clear_bit(ctx_handle, dev->ctx_bitmap); 69 - dev->context_sareas[ctx_handle] = NULL; 70 - mutex_unlock(&dev->struct_mutex); 71 - return; 72 - } 73 - failed: 74 - DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle); 75 - return; 61 + mutex_lock(&dev->struct_mutex); 62 + idr_remove(&dev->ctx_idr, ctx_handle); 63 + mutex_unlock(&dev->struct_mutex); 76 64 } 77 65 78 66 /** ··· 69 81 * \param dev DRM device. 70 82 * \return (non-negative) context handle on success or a negative number on failure. 71 83 * 72 - * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates 73 - * drm_device::context_sareas to accommodate the new entry while holding the 84 + * Allocate a new idr from drm_device::ctx_idr while holding the 74 85 * drm_device::struct_mutex lock. 75 86 */ 76 87 static int drm_ctxbitmap_next(struct drm_device * dev) 77 88 { 78 - int bit; 89 + int new_id; 90 + int ret; 79 91 80 - if (!dev->ctx_bitmap) 81 - return -1; 82 - 92 + again: 93 + if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) { 94 + DRM_ERROR("Out of memory expanding drawable idr\n"); 95 + return -ENOMEM; 96 + } 83 97 mutex_lock(&dev->struct_mutex); 84 - bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); 85 - if (bit < DRM_MAX_CTXBITMAP) { 86 - set_bit(bit, dev->ctx_bitmap); 87 - DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit); 88 - if ((bit + 1) > dev->max_context) { 89 - dev->max_context = (bit + 1); 90 - if (dev->context_sareas) { 91 - struct drm_map **ctx_sareas; 92 - 93 - ctx_sareas = drm_realloc(dev->context_sareas, 94 - (dev->max_context - 95 - 1) * 96 - sizeof(*dev-> 97 - context_sareas), 98 - dev->max_context * 99 - sizeof(*dev-> 100 - context_sareas), 101 - DRM_MEM_MAPS); 102 - if (!ctx_sareas) { 103 - clear_bit(bit, dev->ctx_bitmap); 104 - mutex_unlock(&dev->struct_mutex); 105 - return -1; 106 - } 107 - dev->context_sareas = ctx_sareas; 108 - dev->context_sareas[bit] = NULL; 109 - } else { 110 - /* max_context == 1 at this point */ 111 - dev->context_sareas = 112 - drm_alloc(dev->max_context * 113 - sizeof(*dev->context_sareas), 114 - DRM_MEM_MAPS); 115 - if (!dev->context_sareas) { 116 - clear_bit(bit, dev->ctx_bitmap); 117 - mutex_unlock(&dev->struct_mutex); 118 - return -1; 119 - } 120 - dev->context_sareas[bit] = NULL; 121 - } 122 - } 98 + ret = idr_get_new_above(&dev->ctx_idr, NULL, 99 + DRM_RESERVED_CONTEXTS, &new_id); 100 + if (ret == -EAGAIN) { 123 101 mutex_unlock(&dev->struct_mutex); 124 - return bit; 102 + goto again; 125 103 } 126 104 mutex_unlock(&dev->struct_mutex); 127 - return -1; 105 + return new_id; 128 106 } 129 107 130 108 /** ··· 98 144 * 99 145 * \param dev DRM device. 100 146 * 101 - * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding 102 - * the drm_device::struct_mutex lock. 147 + * Initialise the drm_device::ctx_idr 103 148 */ 104 149 int drm_ctxbitmap_init(struct drm_device * dev) 105 150 { 106 - int i; 107 - int temp; 108 - 109 - mutex_lock(&dev->struct_mutex); 110 - dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE, 111 - DRM_MEM_CTXBITMAP); 112 - if (dev->ctx_bitmap == NULL) { 113 - mutex_unlock(&dev->struct_mutex); 114 - return -ENOMEM; 115 - } 116 - memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE); 117 - dev->context_sareas = NULL; 118 - dev->max_context = -1; 119 - mutex_unlock(&dev->struct_mutex); 120 - 121 - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { 122 - temp = drm_ctxbitmap_next(dev); 123 - DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp); 124 - } 125 - 151 + idr_init(&dev->ctx_idr); 126 152 return 0; 127 153 } 128 154 ··· 111 177 * 112 178 * \param dev DRM device. 113 179 * 114 - * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding 115 - * the drm_device::struct_mutex lock. 180 + * Free all idr members using drm_ctx_sarea_free helper function 181 + * while holding the drm_device::struct_mutex lock. 116 182 */ 117 183 void drm_ctxbitmap_cleanup(struct drm_device * dev) 118 184 { 119 185 mutex_lock(&dev->struct_mutex); 120 - if (dev->context_sareas) 121 - drm_free(dev->context_sareas, 122 - sizeof(*dev->context_sareas) * 123 - dev->max_context, DRM_MEM_MAPS); 124 - drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP); 186 + idr_remove_all(&dev->ctx_idr); 125 187 mutex_unlock(&dev->struct_mutex); 126 188 } 127 189 ··· 136 206 * \param arg user argument pointing to a drm_ctx_priv_map structure. 137 207 * \return zero on success or a negative number on failure. 138 208 * 139 - * Gets the map from drm_device::context_sareas with the handle specified and 209 + * Gets the map from drm_device::ctx_idr with the handle specified and 140 210 * returns its handle. 141 211 */ 142 212 int drm_getsareactx(struct inode *inode, struct file *filp, ··· 153 223 return -EFAULT; 154 224 155 225 mutex_lock(&dev->struct_mutex); 156 - if (dev->max_context < 0 157 - || request.ctx_id >= (unsigned)dev->max_context) { 226 + 227 + map = idr_find(&dev->ctx_idr, request.ctx_id); 228 + if (!map) { 158 229 mutex_unlock(&dev->struct_mutex); 159 230 return -EINVAL; 160 231 } 161 232 162 - map = dev->context_sareas[request.ctx_id]; 163 233 mutex_unlock(&dev->struct_mutex); 164 234 165 235 request.handle = NULL; ··· 188 258 * \return zero on success or a negative number on failure. 189 259 * 190 260 * Searches the mapping specified in \p arg and update the entry in 191 - * drm_device::context_sareas with it. 261 + * drm_device::ctx_idr with it. 192 262 */ 193 263 int drm_setsareactx(struct inode *inode, struct file *filp, 194 264 unsigned int cmd, unsigned long arg) ··· 218 288 map = r_list->map; 219 289 if (!map) 220 290 goto bad; 221 - if (dev->max_context < 0) 291 + 292 + if (IS_ERR(idr_replace(&dev->ctx_idr, map, request.ctx_id))) 222 293 goto bad; 223 - if (request.ctx_id >= (unsigned)dev->max_context) 224 - goto bad; 225 - dev->context_sareas[request.ctx_id] = map; 294 + 226 295 mutex_unlock(&dev->struct_mutex); 227 296 return 0; 228 297 }
+56 -194
drivers/char/drm/drm_drawable.c
··· 44 44 { 45 45 DRM_DEVICE; 46 46 unsigned long irqflags; 47 - int i, j; 48 - u32 *bitfield = dev->drw_bitfield; 49 - unsigned int bitfield_length = dev->drw_bitfield_length; 50 - struct drm_drawable_info **info = dev->drw_info; 51 - unsigned int info_length = dev->drw_info_length; 52 47 struct drm_draw draw; 48 + int new_id = 0; 49 + int ret; 53 50 54 - for (i = 0, j = 0; i < bitfield_length; i++) { 55 - if (bitfield[i] == ~0) 56 - continue; 57 - 58 - for (; j < 8 * sizeof(*bitfield); j++) 59 - if (!(bitfield[i] & (1 << j))) 60 - goto done; 51 + again: 52 + if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { 53 + DRM_ERROR("Out of memory expanding drawable idr\n"); 54 + return -ENOMEM; 61 55 } 62 - done: 63 - 64 - if (i == bitfield_length) { 65 - bitfield_length++; 66 - 67 - bitfield = drm_alloc(bitfield_length * sizeof(*bitfield), 68 - DRM_MEM_BUFS); 69 - 70 - if (!bitfield) { 71 - DRM_ERROR("Failed to allocate new drawable bitfield\n"); 72 - return DRM_ERR(ENOMEM); 73 - } 74 - 75 - if (8 * sizeof(*bitfield) * bitfield_length > info_length) { 76 - info_length += 8 * sizeof(*bitfield); 77 - 78 - info = drm_alloc(info_length * sizeof(*info), 79 - DRM_MEM_BUFS); 80 - 81 - if (!info) { 82 - DRM_ERROR("Failed to allocate new drawable info" 83 - " array\n"); 84 - 85 - drm_free(bitfield, 86 - bitfield_length * sizeof(*bitfield), 87 - DRM_MEM_BUFS); 88 - return DRM_ERR(ENOMEM); 89 - } 90 - } 91 - 92 - bitfield[i] = 0; 93 - } 94 - 95 - draw.handle = i * 8 * sizeof(*bitfield) + j + 1; 96 - DRM_DEBUG("%d\n", draw.handle); 97 56 98 57 spin_lock_irqsave(&dev->drw_lock, irqflags); 99 - 100 - bitfield[i] |= 1 << j; 101 - info[draw.handle - 1] = NULL; 102 - 103 - if (bitfield != dev->drw_bitfield) { 104 - memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length * 105 - sizeof(*bitfield)); 106 - drm_free(dev->drw_bitfield, sizeof(*bitfield) * 107 - dev->drw_bitfield_length, DRM_MEM_BUFS); 108 - dev->drw_bitfield = bitfield; 109 - dev->drw_bitfield_length = bitfield_length; 110 - } 111 - 112 - if (info != dev->drw_info) { 113 - memcpy(info, dev->drw_info, dev->drw_info_length * 114 - sizeof(*info)); 115 - drm_free(dev->drw_info, sizeof(*info) * dev->drw_info_length, 116 - DRM_MEM_BUFS); 117 - dev->drw_info = info; 118 - dev->drw_info_length = info_length; 58 + ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id); 59 + if (ret == -EAGAIN) { 60 + spin_unlock_irqrestore(&dev->drw_lock, irqflags); 61 + goto again; 119 62 } 120 63 121 64 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 65 + 66 + draw.handle = new_id; 67 + 68 + DRM_DEBUG("%d\n", draw.handle); 122 69 123 70 DRM_COPY_TO_USER_IOCTL((struct drm_draw __user *)data, draw, sizeof(draw)); 124 71 ··· 79 132 { 80 133 DRM_DEVICE; 81 134 struct drm_draw draw; 82 - int id, idx; 83 - unsigned int shift; 84 135 unsigned long irqflags; 85 - u32 *bitfield = dev->drw_bitfield; 86 - unsigned int bitfield_length = dev->drw_bitfield_length; 87 - struct drm_drawable_info **info = dev->drw_info; 88 - unsigned int info_length = dev->drw_info_length; 89 136 90 137 DRM_COPY_FROM_USER_IOCTL(draw, (struct drm_draw __user *) data, 91 138 sizeof(draw)); 92 139 93 - id = draw.handle - 1; 94 - idx = id / (8 * sizeof(*bitfield)); 95 - shift = id % (8 * sizeof(*bitfield)); 96 - 97 - if (idx < 0 || idx >= bitfield_length || 98 - !(bitfield[idx] & (1 << shift))) { 99 - DRM_DEBUG("No such drawable %d\n", draw.handle); 100 - return 0; 101 - } 102 - 103 140 spin_lock_irqsave(&dev->drw_lock, irqflags); 104 141 105 - bitfield[idx] &= ~(1 << shift); 142 + drm_free(drm_get_drawable_info(dev, draw.handle), 143 + sizeof(struct drm_drawable_info), DRM_MEM_BUFS); 144 + 145 + idr_remove(&dev->drw_idr, draw.handle); 106 146 107 147 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 108 - 109 - if (info[id]) { 110 - drm_free(info[id]->rects, info[id]->num_rects * 111 - sizeof(struct drm_clip_rect), DRM_MEM_BUFS); 112 - drm_free(info[id], sizeof(**info), DRM_MEM_BUFS); 113 - } 114 - 115 - /* Can we shrink the arrays? */ 116 - if (idx == bitfield_length - 1) { 117 - while (idx >= 0 && !bitfield[idx]) 118 - --idx; 119 - 120 - bitfield_length = idx + 1; 121 - 122 - bitfield = NULL; 123 - 124 - if (bitfield_length) { 125 - if (bitfield_length != dev->drw_bitfield_length) 126 - bitfield = drm_alloc(bitfield_length * 127 - sizeof(*bitfield), 128 - DRM_MEM_BUFS); 129 - 130 - if (!bitfield) { 131 - bitfield = dev->drw_bitfield; 132 - bitfield_length = dev->drw_bitfield_length; 133 - } 134 - } 135 - } 136 - 137 - if (bitfield != dev->drw_bitfield) { 138 - info_length = 8 * sizeof(*bitfield) * bitfield_length; 139 - 140 - if (info_length) { 141 - info = drm_alloc(info_length * sizeof(*info), 142 - DRM_MEM_BUFS); 143 - 144 - if (!info) { 145 - info = dev->drw_info; 146 - info_length = dev->drw_info_length; 147 - } 148 - } else 149 - info = NULL; 150 - 151 - spin_lock_irqsave(&dev->drw_lock, irqflags); 152 - 153 - if (bitfield) 154 - memcpy(bitfield, dev->drw_bitfield, bitfield_length * 155 - sizeof(*bitfield)); 156 - drm_free(dev->drw_bitfield, sizeof(*bitfield) * 157 - dev->drw_bitfield_length, DRM_MEM_BUFS); 158 - dev->drw_bitfield = bitfield; 159 - dev->drw_bitfield_length = bitfield_length; 160 - 161 - if (info != dev->drw_info) { 162 - if (info) 163 - memcpy(info, dev->drw_info, info_length * 164 - sizeof(*info)); 165 - drm_free(dev->drw_info, sizeof(*info) * 166 - dev->drw_info_length, DRM_MEM_BUFS); 167 - dev->drw_info = info; 168 - dev->drw_info_length = info_length; 169 - } 170 - 171 - spin_unlock_irqrestore(&dev->drw_lock, irqflags); 172 - } 173 - 174 148 DRM_DEBUG("%d\n", draw.handle); 175 149 return 0; 176 150 } 177 151 178 - int drm_update_drawable_info(DRM_IOCTL_ARGS) { 152 + int drm_update_drawable_info(DRM_IOCTL_ARGS) 153 + { 179 154 DRM_DEVICE; 180 155 struct drm_update_draw update; 181 - unsigned int id, idx, shift; 182 - u32 *bitfield = dev->drw_bitfield; 183 - unsigned long irqflags, bitfield_length = dev->drw_bitfield_length; 184 - struct drm_drawable_info *info; 156 + unsigned long irqflags; 185 157 struct drm_clip_rect *rects; 158 + struct drm_drawable_info *info; 186 159 int err; 187 160 188 161 DRM_COPY_FROM_USER_IOCTL(update, (struct drm_update_draw __user *) data, 189 162 sizeof(update)); 190 163 191 - id = update.handle - 1; 192 - idx = id / (8 * sizeof(*bitfield)); 193 - shift = id % (8 * sizeof(*bitfield)); 194 - 195 - if (idx < 0 || idx >= bitfield_length || 196 - !(bitfield[idx] & (1 << shift))) { 197 - DRM_ERROR("No such drawable %d\n", update.handle); 198 - return DRM_ERR(EINVAL); 199 - } 200 - 201 - info = dev->drw_info[id]; 202 - 164 + info = idr_find(&dev->drw_idr, update.handle); 203 165 if (!info) { 204 - info = drm_calloc(1, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); 205 - 206 - if (!info) { 207 - DRM_ERROR("Failed to allocate drawable info memory\n"); 208 - return DRM_ERR(ENOMEM); 166 + info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); 167 + if (!info) 168 + return -ENOMEM; 169 + if (IS_ERR(idr_replace(&dev->drw_idr, info, update.handle))) { 170 + DRM_ERROR("No such drawable %d\n", update.handle); 171 + drm_free(info, sizeof(*info), DRM_MEM_BUFS); 172 + return -EINVAL; 209 173 } 210 174 } 211 175 ··· 153 295 154 296 info->rects = rects; 155 297 info->num_rects = update.num; 156 - dev->drw_info[id] = info; 157 298 158 299 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 159 300 160 301 DRM_DEBUG("Updated %d cliprects for drawable %d\n", 161 - info->num_rects, id); 302 + info->num_rects, update.handle); 162 303 break; 163 304 default: 164 305 DRM_ERROR("Invalid update type %d\n", update.type); ··· 167 310 return 0; 168 311 169 312 error: 170 - if (!dev->drw_info[id]) 171 - drm_free(info, sizeof(*info), DRM_MEM_BUFS); 172 - else if (rects != dev->drw_info[id]->rects) 173 - drm_free(rects, update.num * 174 - sizeof(struct drm_clip_rect), DRM_MEM_BUFS); 313 + if (rects != info->rects) 314 + drm_free(rects, update.num * sizeof(struct drm_clip_rect), 315 + DRM_MEM_BUFS); 175 316 176 317 return err; 177 318 } ··· 177 322 /** 178 323 * Caller must hold the drawable spinlock! 179 324 */ 180 - struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id) { 181 - u32 *bitfield = dev->drw_bitfield; 182 - unsigned int idx, shift; 183 - 184 - id--; 185 - idx = id / (8 * sizeof(*bitfield)); 186 - shift = id % (8 * sizeof(*bitfield)); 187 - 188 - if (idx < 0 || idx >= dev->drw_bitfield_length || 189 - !(bitfield[idx] & (1 << shift))) { 190 - DRM_DEBUG("No such drawable %d\n", id); 191 - return NULL; 192 - } 193 - 194 - return dev->drw_info[id]; 325 + struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id) 326 + { 327 + return idr_find(&dev->drw_idr, id); 195 328 } 196 329 EXPORT_SYMBOL(drm_get_drawable_info); 330 + 331 + static int drm_drawable_free(int idr, void *p, void *data) 332 + { 333 + struct drm_drawable_info *info = p; 334 + 335 + if (info) { 336 + drm_free(info->rects, info->num_rects * 337 + sizeof(struct drm_clip_rect), DRM_MEM_BUFS); 338 + drm_free(info, sizeof(*info), DRM_MEM_BUFS); 339 + } 340 + 341 + return 0; 342 + } 343 + 344 + void drm_drawable_free_all(struct drm_device *dev) 345 + { 346 + idr_for_each(&dev->drw_idr, drm_drawable_free, NULL); 347 + idr_remove_all(&dev->drw_idr); 348 + }
+3 -12
drivers/char/drm/drm_drv.c
··· 151 151 if (dev->irq_enabled) 152 152 drm_irq_uninstall(dev); 153 153 154 - /* Free drawable information memory */ 155 - for (i = 0; i < dev->drw_bitfield_length / sizeof(*dev->drw_bitfield); 156 - i++) { 157 - struct drm_drawable_info *info = drm_get_drawable_info(dev, i); 158 - 159 - if (info) { 160 - drm_free(info->rects, info->num_rects * 161 - sizeof(struct drm_clip_rect), DRM_MEM_BUFS); 162 - drm_free(info, sizeof(*info), DRM_MEM_BUFS); 163 - } 164 - } 165 - 166 154 mutex_lock(&dev->struct_mutex); 155 + 156 + /* Free drawable information memory */ 157 + drm_drawable_free_all(dev); 167 158 del_timer(&dev->timer); 168 159 169 160 /* Clear pid list */