xref: /titanic_44/usr/src/uts/common/io/drm/drm_gem.c (revision 2e6e901d9406e1a048063c872149376a6bf7cb63)
1 /*
2  * Copyright (c) 2009, Intel Corporation.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Eric Anholt <eric@anholt.net>
26  *
27  */
28 
29 /*
30  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
31  * Use is subject to license terms.
32  */
33 
34 #include <vm/anon.h>
35 #include <vm/seg_kmem.h>
36 #include <vm/seg_kp.h>
37 #include <vm/seg_map.h>
38 #include <sys/fcntl.h>
39 #include <sys/vnode.h>
40 #include <sys/file.h>
41 #include <sys/bitmap.h>
42 #include <sys/ddi.h>
43 #include <sys/sunddi.h>
44 #include <gfx_private.h>
45 #include "drmP.h"
46 #include "drm.h"
47 
48 /*
49  * @file drm_gem.c
50  *
51  * This file provides some of the base ioctls and library routines for
52  * the graphics memory manager implemented by each device driver.
53  *
54  * Because various devices have different requirements in terms of
55  * synchronization and migration strategies, implementing that is left up to
56  * the driver, and all that the general API provides should be generic --
57  * allocating objects, reading/writing data with the cpu, freeing objects.
58  * Even there, platform-dependent optimizations for reading/writing data with
59  * the CPU mean we'll likely hook those out to driver-specific calls.  However,
60  * the DRI2 implementation wants to have at least allocate/mmap be generic.
61  *
62  * The goal was to have swap-backed object allocation managed through
63  * struct file.  However, file descriptors as handles to a struct file have
64  * two major failings:
65  * - Process limits prevent more than 1024 or so being used at a time by
66  *   default.
67  * - Inability to allocate high fds will aggravate the X Server's select()
68  *   handling, and likely that of many GL client applications as well.
69  *
70  * This led to a plan of using our own integer IDs(called handles, following
71  * DRM terminology) to mimic fds, and implement the fd syscalls we need as
72  * ioctls.  The objects themselves will still include the struct file so
73  * that we can transition to fds if the required kernel infrastructure shows
74  * up at a later date, and as our interface with shmfs for memory allocation.
75  */
76 
77 void
idr_list_init(struct idr_list * head)78 idr_list_init(struct idr_list  *head)
79 {
80 	struct idr_list  *entry;
81 	/* HASH for accelerate */
82 	entry = kmem_zalloc(DRM_GEM_OBJIDR_HASHNODE
83 	    * sizeof (struct idr_list), KM_SLEEP);
84 	head->next = entry;
85 	for (int i = 0; i < DRM_GEM_OBJIDR_HASHNODE; i++) {
86 		INIT_LIST_HEAD(&entry[i]);
87 	}
88 }
89 
90 int
idr_list_get_new_above(struct idr_list * head,struct drm_gem_object * obj,int * handlep)91 idr_list_get_new_above(struct idr_list	*head,
92 			struct drm_gem_object *obj,
93 			int *handlep)
94 {
95 	struct idr_list  *entry;
96 	int key;
97 	entry = kmem_zalloc(sizeof (*entry), KM_SLEEP);
98 	key = obj->name % DRM_GEM_OBJIDR_HASHNODE;
99 	list_add(entry, &head->next[key], NULL);
100 	entry->obj = obj;
101 	entry->handle = obj->name;
102 	*handlep = obj->name;
103 	return (0);
104 }
105 
106 struct drm_gem_object *
idr_list_find(struct idr_list * head,uint32_t name)107 idr_list_find(struct idr_list  *head,
108 		uint32_t	name)
109 {
110 	struct idr_list  *entry;
111 	int key;
112 	key = name % DRM_GEM_OBJIDR_HASHNODE;
113 
114 	list_for_each(entry, &head->next[key]) {
115 		if (entry->handle == name)
116 			return (entry->obj);
117 	}
118 	return (NULL);
119 }
120 
121 int
idr_list_remove(struct idr_list * head,uint32_t name)122 idr_list_remove(struct idr_list  *head,
123 		uint32_t	name)
124 {
125 	struct idr_list  *entry, *temp;
126 	int key;
127 	key = name % DRM_GEM_OBJIDR_HASHNODE;
128 	list_for_each_safe(entry, temp, &head->next[key]) {
129 		if (entry->handle == name) {
130 			list_del(entry);
131 			kmem_free(entry, sizeof (*entry));
132 			return (0);
133 		}
134 	}
135 	DRM_ERROR("Failed to remove the object %d", name);
136 	return (-1);
137 }
138 
139 void
idr_list_free(struct idr_list * head)140 idr_list_free(struct idr_list  *head)
141 {
142 	struct idr_list  *entry, *temp;
143 	for (int key = 0; key < DRM_GEM_OBJIDR_HASHNODE; key++) {
144 		list_for_each_safe(entry, temp, &head->next[key]) {
145 			list_del(entry);
146 			kmem_free(entry, sizeof (*entry));
147 		}
148 	}
149 	kmem_free(head->next,
150 	    DRM_GEM_OBJIDR_HASHNODE * sizeof (struct idr_list));
151 	head->next = NULL;
152 }
153 
154 int
idr_list_empty(struct idr_list * head)155 idr_list_empty(struct idr_list  *head)
156 {
157 	int empty;
158 	for (int key = 0; key < DRM_GEM_OBJIDR_HASHNODE; key++) {
159 		empty = list_empty(&(head)->next[key]);
160 		if (!empty)
161 			return (empty);
162 	}
163 	return (1);
164 }
165 
166 static	uint32_t	shfile_name = 0;
167 #define	SHFILE_NAME_MAX	0xffffffff
168 
169 /*
170  * will be set to 1 for 32 bit x86 systems only, in startup.c
171  */
172 extern int	segkp_fromheap;
173 extern ulong_t *segkp_bitmap;
174 
175 void
drm_gem_object_reference(struct drm_gem_object * obj)176 drm_gem_object_reference(struct drm_gem_object *obj)
177 {
178 	atomic_inc(&obj->refcount);
179 }
180 
181 void
drm_gem_object_unreference(struct drm_gem_object * obj)182 drm_gem_object_unreference(struct drm_gem_object *obj)
183 {
184 	if (obj == NULL)
185 		return;
186 
187 	atomic_sub(1, &obj->refcount);
188 	if (obj->refcount == 0)
189 		drm_gem_object_free(obj);
190 }
191 
192 void
drm_gem_object_handle_reference(struct drm_gem_object * obj)193 drm_gem_object_handle_reference(struct drm_gem_object *obj)
194 {
195 	drm_gem_object_reference(obj);
196 	atomic_inc(&obj->handlecount);
197 }
198 
199 void
drm_gem_object_handle_unreference(struct drm_gem_object * obj)200 drm_gem_object_handle_unreference(struct drm_gem_object *obj)
201 {
202 	if (obj == NULL)
203 		return;
204 
205 	/*
206 	 * Must bump handle count first as this may be the last
207 	 * ref, in which case the object would disappear before we
208 	 * checked for a name
209 	 */
210 	atomic_sub(1, &obj->handlecount);
211 	if (obj->handlecount == 0)
212 		drm_gem_object_handle_free(obj);
213 	drm_gem_object_unreference(obj);
214 }
215 
216 /*
217  * Initialize the GEM device fields
218  */
219 
220 int
drm_gem_init(struct drm_device * dev)221 drm_gem_init(struct drm_device *dev)
222 {
223 	mutex_init(&dev->object_name_lock, NULL, MUTEX_DRIVER, NULL);
224 	idr_list_init(&dev->object_name_idr);
225 
226 	atomic_set(&dev->object_count, 0);
227 	atomic_set(&dev->object_memory, 0);
228 	atomic_set(&dev->pin_count, 0);
229 	atomic_set(&dev->pin_memory, 0);
230 	atomic_set(&dev->gtt_count, 0);
231 	atomic_set(&dev->gtt_memory, 0);
232 	return (0);
233 }
234 
235 /*
236  * Allocate a GEM object of the specified size with shmfs backing store
237  */
238 struct drm_gem_object *
drm_gem_object_alloc(struct drm_device * dev,size_t size)239 drm_gem_object_alloc(struct drm_device *dev, size_t size)
240 {
241 	static ddi_dma_attr_t dma_attr = {
242 		DMA_ATTR_V0,
243 		0U,				/* dma_attr_addr_lo */
244 		0xffffffffU,			/* dma_attr_addr_hi */
245 		0xffffffffU,			/* dma_attr_count_max */
246 		4096,				/* dma_attr_align */
247 		0x1fffU,			/* dma_attr_burstsizes */
248 		1,				/* dma_attr_minxfer */
249 		0xffffffffU,			/* dma_attr_maxxfer */
250 		0xffffffffU,			/* dma_attr_seg */
251 		1,				/* dma_attr_sgllen, variable */
252 		4,				/* dma_attr_granular */
253 		0				/* dma_attr_flags */
254 	};
255 	static ddi_device_acc_attr_t acc_attr = {
256 		DDI_DEVICE_ATTR_V0,
257 		DDI_NEVERSWAP_ACC,
258 		DDI_MERGING_OK_ACC
259 	};
260 	struct drm_gem_object *obj;
261 	ddi_dma_cookie_t cookie;
262 	uint_t cookie_cnt;
263 	drm_local_map_t *map;
264 
265 	pgcnt_t real_pgcnt, pgcnt = btopr(size);
266 	uint32_t paddr, cookie_end;
267 	int i, n;
268 
269 	obj = kmem_zalloc(sizeof (struct drm_gem_object), KM_NOSLEEP);
270 	if (obj == NULL)
271 		return (NULL);
272 
273 	obj->dev = dev;
274 	obj->flink = 0;
275 	obj->size = size;
276 
277 	if (shfile_name == SHFILE_NAME_MAX) {
278 		DRM_ERROR("No name space for object");
279 		goto err1;
280 	} else {
281 		obj->name = ++shfile_name;
282 	}
283 
284 	dma_attr.dma_attr_sgllen = (int)pgcnt;
285 
286 	if (ddi_dma_alloc_handle(dev->dip, &dma_attr,
287 	    DDI_DMA_DONTWAIT, NULL, &obj->dma_hdl)) {
288 		DRM_ERROR("drm_gem_object_alloc: "
289 		    "ddi_dma_alloc_handle failed");
290 		goto err1;
291 	}
292 	if (ddi_dma_mem_alloc(obj->dma_hdl, ptob(pgcnt), &acc_attr,
293 	    IOMEM_DATA_UC_WR_COMBINE, DDI_DMA_DONTWAIT, NULL,
294 	    &obj->kaddr, &obj->real_size, &obj->acc_hdl)) {
295 		DRM_ERROR("drm_gem_object_alloc: "
296 		    "ddi_dma_mem_alloc failed");
297 		goto err2;
298 	}
299 	if (ddi_dma_addr_bind_handle(obj->dma_hdl, NULL,
300 	    obj->kaddr, obj->real_size, DDI_DMA_RDWR,
301 	    DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_cnt)
302 	    != DDI_DMA_MAPPED) {
303 		DRM_ERROR("drm_gem_object_alloc: "
304 		    "ddi_dma_addr_bind_handle failed");
305 		goto err3;
306 	}
307 
308 	real_pgcnt = btopr(obj->real_size);
309 
310 	obj->pfnarray = kmem_zalloc(real_pgcnt * sizeof (pfn_t), KM_NOSLEEP);
311 	if (obj->pfnarray == NULL) {
312 		goto err4;
313 	}
314 	for (n = 0, i = 1; ; i++) {
315 		for (paddr = cookie.dmac_address,
316 		    cookie_end = cookie.dmac_address + cookie.dmac_size;
317 		    paddr < cookie_end;
318 		    paddr += PAGESIZE) {
319 			obj->pfnarray[n++] = btop(paddr);
320 			if (n >= real_pgcnt)
321 				goto addmap;
322 		}
323 		if (i >= cookie_cnt)
324 			break;
325 		ddi_dma_nextcookie(obj->dma_hdl, &cookie);
326 	}
327 
328 addmap:
329 	map = drm_alloc(sizeof (struct drm_local_map), DRM_MEM_MAPS);
330 	if (map == NULL) {
331 		goto err5;
332 	}
333 
334 	map->handle = obj;
335 	map->offset = (uintptr_t)map->handle;
336 	map->offset &= 0xffffffffUL;
337 	map->dev_addr = map->handle;
338 	map->size = obj->real_size;
339 	map->type = _DRM_TTM;
340 	map->flags = _DRM_WRITE_COMBINING | _DRM_REMOVABLE;
341 	map->drm_umem_cookie =
342 	    gfxp_umem_cookie_init(obj->kaddr, obj->real_size);
343 	if (map->drm_umem_cookie == NULL) {
344 		goto err6;
345 	}
346 
347 	obj->map = map;
348 
349 	atomic_set(&obj->refcount, 1);
350 	atomic_set(&obj->handlecount, 1);
351 	if (dev->driver->gem_init_object != NULL &&
352 	    dev->driver->gem_init_object(obj) != 0) {
353 		goto err7;
354 	}
355 	atomic_inc(&dev->object_count);
356 	atomic_add(obj->size, &dev->object_memory);
357 
358 	return (obj);
359 
360 err7:
361 	gfxp_umem_cookie_destroy(map->drm_umem_cookie);
362 err6:
363 	drm_free(map, sizeof (struct drm_local_map), DRM_MEM_MAPS);
364 err5:
365 	kmem_free(obj->pfnarray, real_pgcnt * sizeof (pfn_t));
366 err4:
367 	(void) ddi_dma_unbind_handle(obj->dma_hdl);
368 err3:
369 	ddi_dma_mem_free(&obj->acc_hdl);
370 err2:
371 	ddi_dma_free_handle(&obj->dma_hdl);
372 err1:
373 	kmem_free(obj, sizeof (struct drm_gem_object));
374 
375 	return (NULL);
376 }
377 
378 /*
379  * Removes the mapping from handle to filp for this object.
380  */
381 static int
drm_gem_handle_delete(struct drm_file * filp,int handle)382 drm_gem_handle_delete(struct drm_file *filp, int handle)
383 {
384 	struct drm_device *dev;
385 	struct drm_gem_object *obj;
386 	int err;
387 	/*
388 	 * This is gross. The idr system doesn't let us try a delete and
389 	 * return an error code.  It just spews if you fail at deleting.
390 	 * So, we have to grab a lock around finding the object and then
391 	 * doing the delete on it and dropping the refcount, or the user
392 	 * could race us to double-decrement the refcount and cause a
393 	 * use-after-free later.  Given the frequency of our handle lookups,
394 	 * we may want to use ida for number allocation and a hash table
395 	 * for the pointers, anyway.
396 	 */
397 	spin_lock(&filp->table_lock);
398 
399 	/* Check if we currently have a reference on the object */
400 	obj = idr_list_find(&filp->object_idr, handle);
401 	if (obj == NULL) {
402 		spin_unlock(&filp->table_lock);
403 		DRM_ERROR("obj %d is not in tne list, failed to close", handle);
404 		return (EINVAL);
405 	}
406 	dev = obj->dev;
407 
408 	/* Release reference and decrement refcount. */
409 	err = idr_list_remove(&filp->object_idr, handle);
410 	if (err == -1)
411 		DRM_ERROR("%s", __func__);
412 
413 	spin_unlock(&filp->table_lock);
414 
415 	spin_lock(&dev->struct_mutex);
416 	drm_gem_object_handle_unreference(obj);
417 	spin_unlock(&dev->struct_mutex);
418 	return (0);
419 }
420 
421 /*
422  * Create a handle for this object. This adds a handle reference
423  * to the object, which includes a regular reference count. Callers
424  * will likely want to dereference the object afterwards.
425  */
426 int
drm_gem_handle_create(struct drm_file * file_priv,struct drm_gem_object * obj,int * handlep)427 drm_gem_handle_create(struct drm_file *file_priv,
428 		    struct drm_gem_object *obj,
429 		    int *handlep)
430 {
431 	int	ret;
432 
433 	/*
434 	 * Get the user-visible handle using idr.
435 	 */
436 again:
437 	/* ensure there is space available to allocate a handle */
438 
439 	/* do the allocation under our spinlock */
440 	spin_lock(&file_priv->table_lock);
441 	ret = idr_list_get_new_above(&file_priv->object_idr, obj, handlep);
442 	spin_unlock(&file_priv->table_lock);
443 	if (ret == -EAGAIN)
444 		goto again;
445 
446 	if (ret != 0) {
447 		DRM_ERROR("Failed to create handle");
448 		return (ret);
449 	}
450 
451 	drm_gem_object_handle_reference(obj);
452 	return (0);
453 }
454 
455 /* Returns a reference to the object named by the handle. */
456 struct drm_gem_object *
drm_gem_object_lookup(struct drm_file * filp,int handle)457 drm_gem_object_lookup(struct drm_file *filp,
458 			    int handle)
459 {
460 	struct drm_gem_object *obj;
461 
462 	spin_lock(&filp->table_lock);
463 
464 	/* Check if we currently have a reference on the object */
465 	obj = idr_list_find(&filp->object_idr, handle);
466 		if (obj == NULL) {
467 			spin_unlock(&filp->table_lock);
468 			DRM_ERROR("object_lookup failed, handle %d", handle);
469 			return (NULL);
470 		}
471 
472 	drm_gem_object_reference(obj);
473 
474 	spin_unlock(&filp->table_lock);
475 
476 	return (obj);
477 }
478 
479 /*
480  * Releases the handle to an mm object.
481  */
482 /*ARGSUSED*/
483 int
drm_gem_close_ioctl(DRM_IOCTL_ARGS)484 drm_gem_close_ioctl(DRM_IOCTL_ARGS)
485 {
486 	DRM_DEVICE;
487 	struct drm_gem_close args;
488 	int ret;
489 
490 	if (!(dev->driver->use_gem == 1))
491 		return (ENODEV);
492 
493 	DRM_COPYFROM_WITH_RETURN(&args,
494 	    (void *)data, sizeof (args));
495 
496 	ret = drm_gem_handle_delete(fpriv, args.handle);
497 
498 	return (ret);
499 }
500 
501 /*
502  * Create a global name for an object, returning the name.
503  *
504  * Note that the name does not hold a reference; when the object
505  * is freed, the name goes away.
506  */
507 /*ARGSUSED*/
508 int
drm_gem_flink_ioctl(DRM_IOCTL_ARGS)509 drm_gem_flink_ioctl(DRM_IOCTL_ARGS)
510 {
511 	DRM_DEVICE;
512 	struct drm_gem_flink args;
513 	struct drm_gem_object *obj;
514 	int ret, handle;
515 
516 	if (!(dev->driver->use_gem == 1))
517 		return (ENODEV);
518 
519 	DRM_COPYFROM_WITH_RETURN(&args,
520 	    (void *)data, sizeof (args));
521 	obj = drm_gem_object_lookup(fpriv, args.handle);
522 	if (obj == NULL)
523 		return (EINVAL);
524 	handle = args.handle;
525 	spin_lock(&dev->object_name_lock);
526 	if (!obj->flink) {
527 		/* only creat a node in object_name_idr, no update anything */
528 		ret = idr_list_get_new_above(&dev->object_name_idr,
529 		    obj, &handle);
530 		obj->flink = obj->name;
531 		/* Allocate a reference for the name table.  */
532 		drm_gem_object_reference(obj);
533 	}
534 	/*
535 	 * Leave the reference from the lookup around as the
536 	 * name table now holds one
537 	 */
538 	args.name = obj->name;
539 
540 	spin_unlock(&dev->object_name_lock);
541 	ret = DRM_COPY_TO_USER((void *) data, &args, sizeof (args));
542 	if (ret != 0)
543 		DRM_ERROR(" gem flink error! %d", ret);
544 
545 	spin_lock(&dev->struct_mutex);
546 	drm_gem_object_unreference(obj);
547 	spin_unlock(&dev->struct_mutex);
548 
549 	return (ret);
550 }
551 
552 /*
553  * Open an object using the global name, returning a handle and the size.
554  *
555  * This handle (of course) holds a reference to the object, so the object
556  * will not go away until the handle is deleted.
557  */
558 /*ARGSUSED*/
559 int
drm_gem_open_ioctl(DRM_IOCTL_ARGS)560 drm_gem_open_ioctl(DRM_IOCTL_ARGS)
561 {
562 	DRM_DEVICE;
563 	struct drm_gem_open args;
564 	struct drm_gem_object *obj;
565 	int ret;
566 	int handle;
567 
568 	if (!(dev->driver->use_gem == 1)) {
569 		DRM_ERROR("Not support GEM");
570 		return (ENODEV);
571 	}
572 	DRM_COPYFROM_WITH_RETURN(&args,
573 	    (void *) data, sizeof (args));
574 
575 	spin_lock(&dev->object_name_lock);
576 
577 	obj = idr_list_find(&dev->object_name_idr, args.name);
578 
579 	if (obj)
580 		drm_gem_object_reference(obj);
581 	spin_unlock(&dev->object_name_lock);
582 	if (!obj) {
583 		DRM_ERROR("Can't find the obj %d", args.name);
584 		return (ENOENT);
585 	}
586 
587 	ret = drm_gem_handle_create(fpriv, obj, &handle);
588 	spin_lock(&dev->struct_mutex);
589 	drm_gem_object_unreference(obj);
590 	spin_unlock(&dev->struct_mutex);
591 
592 	args.handle = args.name;
593 	args.size = obj->size;
594 
595 	ret = DRM_COPY_TO_USER((void *) data, &args, sizeof (args));
596 	if (ret != 0)
597 		DRM_ERROR(" gem open error! %d", ret);
598 	return (ret);
599 }
600 
601 /*
602  * Called at device open time, sets up the structure for handling refcounting
603  * of mm objects.
604  */
605 void
drm_gem_open(struct drm_file * file_private)606 drm_gem_open(struct drm_file *file_private)
607 {
608 	idr_list_init(&file_private->object_idr);
609 	mutex_init(&file_private->table_lock, NULL, MUTEX_DRIVER, NULL);
610 }
611 
612 /*
613  * Called at device close to release the file's
614  * handle references on objects.
615  */
616 static void
drm_gem_object_release_handle(struct drm_gem_object * obj)617 drm_gem_object_release_handle(struct drm_gem_object *obj)
618 {
619 	drm_gem_object_handle_unreference(obj);
620 }
621 
622 /*
623  * Called at close time when the filp is going away.
624  *
625  * Releases any remaining references on objects by this filp.
626  */
627 void
drm_gem_release(struct drm_device * dev,struct drm_file * file_private)628 drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
629 {
630 	struct idr_list  *entry;
631 	spin_lock(&dev->struct_mutex);
632 
633 	idr_list_for_each(entry, &file_private->object_idr)
634 	    drm_gem_object_release_handle(entry->obj);
635 
636 	idr_list_free(&file_private->object_idr);
637 	spin_unlock(&dev->struct_mutex);
638 
639 }
640 
641 /*
642  * Called after the last reference to the object has been lost.
643  *
644  * Frees the object
645  */
646 void
drm_gem_object_free(struct drm_gem_object * obj)647 drm_gem_object_free(struct drm_gem_object *obj)
648 {
649 	struct drm_device *dev = obj->dev;
650 	struct drm_local_map *map = obj->map;
651 
652 	if (dev->driver->gem_free_object != NULL)
653 		dev->driver->gem_free_object(obj);
654 
655 	gfxp_umem_cookie_destroy(map->drm_umem_cookie);
656 	drm_free(map, sizeof (struct drm_local_map), DRM_MEM_MAPS);
657 
658 	kmem_free(obj->pfnarray, btopr(obj->real_size) * sizeof (pfn_t));
659 
660 	(void) ddi_dma_unbind_handle(obj->dma_hdl);
661 	ddi_dma_mem_free(&obj->acc_hdl);
662 	ddi_dma_free_handle(&obj->dma_hdl);
663 
664 	atomic_dec(&dev->object_count);
665 	atomic_sub(obj->size, &dev->object_memory);
666 	kmem_free(obj, sizeof (struct drm_gem_object));
667 }
668 
669 /*
670  * Called after the last handle to the object has been closed
671  *
672  * Removes any name for the object. Note that this must be
673  * called before drm_gem_object_free or we'll be touching
674  * freed memory
675  */
676 void
drm_gem_object_handle_free(struct drm_gem_object * obj)677 drm_gem_object_handle_free(struct drm_gem_object *obj)
678 {
679 	int err;
680 	struct drm_device *dev = obj->dev;
681 	/* Remove any name for this object */
682 	spin_lock(&dev->object_name_lock);
683 	if (obj->flink) {
684 		err = idr_list_remove(&dev->object_name_idr, obj->name);
685 		if (err == -1)
686 			DRM_ERROR("%s", __func__);
687 		obj->flink = 0;
688 		spin_unlock(&dev->object_name_lock);
689 		/*
690 		 * The object name held a reference to this object, drop
691 		 * that now.
692 		 */
693 		drm_gem_object_unreference(obj);
694 	} else
695 
696 		spin_unlock(&dev->object_name_lock);
697 
698 }
699