Subversion Repositories Kolibri OS

Rev

Rev 4075 | Rev 4246 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4075 Rev 4104
Line 30... Line 30...
30
#include 
30
#include 
31
#include 
31
#include 
32
#include 
32
#include 
33
#include 
33
#include 
34
#include 
34
#include 
-
 
35
#include 
Line 35... Line 36...
35
 
36
 
36
/** @file drm_gem.c
37
/** @file drm_gem.c
37
 *
38
 *
38
 * This file provides some of the base ioctls and library routines for
39
 * This file provides some of the base ioctls and library routines for
Line 76... Line 77...
76
#else
77
#else
77
#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1)
78
#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1)
78
#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16)
79
#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16)
79
#endif
80
#endif
Line 80... Line -...
80
 
-
 
81
#if 0
81
 
82
/**
82
/**
83
 * Initialize the GEM device fields
83
 * Initialize the GEM device fields
Line 84... Line 84...
84
 */
84
 */
85
 
85
 
86
int
86
int
87
drm_gem_init(struct drm_device *dev)
87
drm_gem_init(struct drm_device *dev)
Line 88... Line 88...
88
{
88
{
89
	struct drm_gem_mm *mm;
89
	struct drm_gem_mm *mm;
Line 90... Line 90...
90
 
90
 
91
	spin_lock_init(&dev->object_name_lock);
91
	mutex_init(&dev->object_name_lock);
92
	idr_init(&dev->object_name_idr);
92
	idr_init(&dev->object_name_idr);
93
 
93
 
94
	mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL);
94
	mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL);
Line 95... Line 95...
95
	if (!mm) {
95
	if (!mm) {
96
		DRM_ERROR("out of memory\n");
-
 
97
		return -ENOMEM;
96
		DRM_ERROR("out of memory\n");
98
	}
-
 
99
 
-
 
100
	dev->mm_private = mm;
-
 
101
 
-
 
102
	if (drm_ht_create(&mm->offset_hash, 12)) {
97
		return -ENOMEM;
103
		kfree(mm);
98
	}
Line 104... Line 99...
104
		return -ENOMEM;
99
 
105
	}
100
	dev->mm_private = mm;
Line 106... Line 101...
106
 
101
	drm_vma_offset_manager_init(&mm->vma_manager,
107
	drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
102
				    DRM_FILE_PAGE_OFFSET_START,
108
		    DRM_FILE_PAGE_OFFSET_SIZE);
103
		    DRM_FILE_PAGE_OFFSET_SIZE);
109
 
104
 
Line 110... Line 105...
110
	return 0;
105
	return 0;
111
}
-
 
112
 
106
}
113
void
107
 
114
drm_gem_destroy(struct drm_device *dev)
108
void
115
{
-
 
Line 116... Line 109...
116
	struct drm_gem_mm *mm = dev->mm_private;
109
drm_gem_destroy(struct drm_device *dev)
117
 
110
{
118
	drm_mm_takedown(&mm->offset_manager);
111
	struct drm_gem_mm *mm = dev->mm_private;
119
	drm_ht_remove(&mm->offset_hash);
112
 
120
	kfree(mm);
113
	drm_vma_offset_manager_destroy(&mm->vma_manager);
121
	dev->mm_private = NULL;
114
	kfree(mm);
122
}
115
	dev->mm_private = NULL;
123
#endif
116
}
Line 124... Line -...
124
 
-
 
125
/**
117
 
126
 * Initialize an already allocated GEM object of the specified size with
118
/**
127
 * shmfs backing store.
119
 * Initialize an already allocated GEM object of the specified size with
Line 128... Line -...
128
 */
-
 
129
int drm_gem_object_init(struct drm_device *dev,
120
 * shmfs backing store.
130
			struct drm_gem_object *obj, size_t size)
121
 */
Line 131... Line 122...
131
{
122
int drm_gem_object_init(struct drm_device *dev,
132
	BUG_ON((size & (PAGE_SIZE - 1)) != 0);
123
			struct drm_gem_object *obj, size_t size)
133
 
124
{
Line 134... Line 125...
134
	obj->dev = dev;
125
	struct file *filp;
135
	obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
126
 
136
	if (IS_ERR(obj->filp))
127
	filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
137
		return PTR_ERR(obj->filp);
128
	if (IS_ERR(filp))
138
 
129
		return PTR_ERR(filp);
139
	kref_init(&obj->refcount);
130
 
140
	atomic_set(&obj->handle_count, 0);
131
	drm_gem_private_object_init(dev, obj, size);
141
	obj->size = size;
132
	obj->filp = filp;
142
 
133
 
Line 143... Line 134...
143
	return 0;
134
	return 0;
144
}
135
}
Line 145... Line 136...
145
EXPORT_SYMBOL(drm_gem_object_init);
136
EXPORT_SYMBOL(drm_gem_object_init);
146
 
137
 
147
/**
138
/**
148
 * Initialize an already allocated GEM object of the specified size with
-
 
149
 * no GEM provided backing store. Instead the caller is responsible for
139
 * Initialize an already allocated GEM object of the specified size with
150
 * backing the object and handling it.
140
 * no GEM provided backing store. Instead the caller is responsible for
151
 */
141
 * backing the object and handling it.
Line 152... Line 142...
152
int drm_gem_private_object_init(struct drm_device *dev,
142
 */
153
			struct drm_gem_object *obj, size_t size)
143
void drm_gem_private_object_init(struct drm_device *dev,
Line 192... Line 182...
192
	kfree(obj);
182
	kfree(obj);
193
	return NULL;
183
	return NULL;
194
}
184
}
195
EXPORT_SYMBOL(drm_gem_object_alloc);
185
EXPORT_SYMBOL(drm_gem_object_alloc);
Line -... Line 186...
-
 
186
 
-
 
187
static void drm_gem_object_ref_bug(struct kref *list_kref)
-
 
188
{
-
 
189
	BUG();
-
 
190
}
-
 
191
 
-
 
192
/**
-
 
193
 * Called after the last handle to the object has been closed
-
 
194
 *
-
 
195
 * Removes any name for the object. Note that this must be
-
 
196
 * called before drm_gem_object_free or we'll be touching
-
 
197
 * freed memory
-
 
198
 */
-
 
199
static void drm_gem_object_handle_free(struct drm_gem_object *obj)
-
 
200
{
-
 
201
	struct drm_device *dev = obj->dev;
-
 
202
 
-
 
203
	/* Remove any name for this object */
-
 
204
	if (obj->name) {
-
 
205
		idr_remove(&dev->object_name_idr, obj->name);
-
 
206
		obj->name = 0;
-
 
207
		/*
-
 
208
		 * The object name held a reference to this object, drop
-
 
209
		 * that now.
-
 
210
		*
-
 
211
		* This cannot be the last reference, since the handle holds one too.
-
 
212
		 */
-
 
213
		kref_put(&obj->refcount, drm_gem_object_ref_bug);
-
 
214
	}
-
 
215
}
-
 
216
 
-
 
217
 
-
 
218
static void
-
 
219
drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
-
 
220
{
-
 
221
	if (WARN_ON(obj->handle_count == 0))
-
 
222
		return;
-
 
223
 
-
 
224
	/*
-
 
225
	* Must bump handle count first as this may be the last
-
 
226
	* ref, in which case the object would disappear before we
-
 
227
	* checked for a name
-
 
228
	*/
-
 
229
 
-
 
230
	mutex_lock(&obj->dev->object_name_lock);
-
 
231
	if (--obj->handle_count == 0) {
-
 
232
		drm_gem_object_handle_free(obj);
-
 
233
	}
-
 
234
	mutex_unlock(&obj->dev->object_name_lock);
-
 
235
 
-
 
236
	drm_gem_object_unreference_unlocked(obj);
Line 196... Line 237...
196
 
237
}
197
 
238
 
198
/**
239
/**
199
 * Removes the mapping from handle to filp for this object.
240
 * Removes the mapping from handle to filp for this object.
Line 246... Line 287...
246
 * Create a handle for this object. This adds a handle reference
287
 * Create a handle for this object. This adds a handle reference
247
 * to the object, which includes a regular reference count. Callers
288
 * to the object, which includes a regular reference count. Callers
248
 * will likely want to dereference the object afterwards.
289
 * will likely want to dereference the object afterwards.
249
 */
290
 */
250
int
291
int
251
drm_gem_handle_create(struct drm_file *file_priv,
292
drm_gem_handle_create_tail(struct drm_file *file_priv,
252
		       struct drm_gem_object *obj,
293
		       struct drm_gem_object *obj,
253
		       u32 *handlep)
294
		       u32 *handlep)
254
{
295
{
255
	struct drm_device *dev = obj->dev;
296
	struct drm_device *dev = obj->dev;
256
	int ret;
297
	int ret;
Line -... Line 298...
-
 
298
 
-
 
299
	WARN_ON(!mutex_is_locked(&dev->object_name_lock));
257
 
300
 
258
	/*
301
	/*
259
	 * Get the user-visible handle using idr.  Preload and perform
302
	 * Get the user-visible handle using idr.  Preload and perform
260
	 * allocation under our spinlock.
303
	 * allocation under our spinlock.
261
	 */
304
	 */
262
	idr_preload(GFP_KERNEL);
305
	idr_preload(GFP_KERNEL);
Line 263... Line 306...
263
	spin_lock(&file_priv->table_lock);
306
	spin_lock(&file_priv->table_lock);
264
 
-
 
-
 
307
 
-
 
308
	ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
265
	ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
309
	drm_gem_object_reference(obj);
266
 
310
	obj->handle_count++;
-
 
311
	spin_unlock(&file_priv->table_lock);
267
	spin_unlock(&file_priv->table_lock);
312
	idr_preload_end();
-
 
313
	mutex_unlock(&dev->object_name_lock);
268
	idr_preload_end();
314
	if (ret < 0) {
-
 
315
		drm_gem_object_handle_unreference_unlocked(obj);
269
	if (ret < 0)
316
		return ret;
Line -... Line 317...
-
 
317
	}
-
 
318
	*handlep = ret;
270
		return ret;
319
 
-
 
320
//   ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp);
-
 
321
//   if (ret) {
Line 271... Line 322...
271
	*handlep = ret;
322
//       drm_gem_handle_delete(file_priv, *handlep);
272
 
323
//       return ret;
273
	drm_gem_object_handle_reference(obj);
324
//   }
274
 
325
 
Line 280... Line 331...
280
		}
331
		}
281
	}
332
	}
Line 282... Line 333...
282
 
333
 
283
	return 0;
334
	return 0;
-
 
335
}
-
 
336
 
-
 
337
/**
-
 
338
 * Create a handle for this object. This adds a handle reference
-
 
339
 * to the object, which includes a regular reference count. Callers
-
 
340
 * will likely want to dereference the object afterwards.
-
 
341
 */
-
 
342
int
-
 
343
drm_gem_handle_create(struct drm_file *file_priv,
-
 
344
		       struct drm_gem_object *obj,
-
 
345
		       u32 *handlep)
-
 
346
{
-
 
347
	mutex_lock(&obj->dev->object_name_lock);
-
 
348
 
-
 
349
	return drm_gem_handle_create_tail(file_priv, obj, handlep);
284
}
350
}
Line 285... Line 351...
285
EXPORT_SYMBOL(drm_gem_handle_create);
351
EXPORT_SYMBOL(drm_gem_handle_create);
286
 
352
 
Line 295... Line 361...
295
void
361
void
296
drm_gem_free_mmap_offset(struct drm_gem_object *obj)
362
drm_gem_free_mmap_offset(struct drm_gem_object *obj)
297
{
363
{
298
	struct drm_device *dev = obj->dev;
364
	struct drm_device *dev = obj->dev;
299
	struct drm_gem_mm *mm = dev->mm_private;
365
	struct drm_gem_mm *mm = dev->mm_private;
300
	struct drm_map_list *list = &obj->map_list;
-
 
Line 301... Line 366...
301
 
366
 
302
	drm_ht_remove_item(&mm->offset_hash, &list->hash);
-
 
303
	drm_mm_put_block(list->file_offset_node);
-
 
304
	kfree(list->map);
-
 
305
	list->map = NULL;
367
	drm_vma_offset_remove(&mm->vma_manager, &obj->vma_node);
306
}
368
}
Line 307... Line 369...
307
EXPORT_SYMBOL(drm_gem_free_mmap_offset);
369
EXPORT_SYMBOL(drm_gem_free_mmap_offset);
308
 
370
 
309
/**
371
/**
-
 
372
 * drm_gem_create_mmap_offset_size - create a fake mmap offset for an object
310
 * drm_gem_create_mmap_offset - create a fake mmap offset for an object
373
 * @obj: obj in question
311
 * @obj: obj in question
374
 * @size: the virtual size
312
 *
375
 *
313
 * GEM memory mapping works by handing back to userspace a fake mmap offset
376
 * GEM memory mapping works by handing back to userspace a fake mmap offset
314
 * it can use in a subsequent mmap(2) call.  The DRM core code then looks
377
 * it can use in a subsequent mmap(2) call.  The DRM core code then looks
315
 * up the object based on the offset and sets up the various memory mapping
378
 * up the object based on the offset and sets up the various memory mapping
316
 * structures.
379
 * structures.
-
 
380
 *
-
 
381
 * This routine allocates and attaches a fake offset for @obj, in cases where
317
 *
382
 * the virtual size differs from the physical size (ie. obj->size).  Otherwise
318
 * This routine allocates and attaches a fake offset for @obj.
383
 * just use drm_gem_create_mmap_offset().
319
 */
384
 */
320
int
385
int
321
drm_gem_create_mmap_offset(struct drm_gem_object *obj)
386
drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size)
322
{
387
{
323
	struct drm_device *dev = obj->dev;
-
 
324
	struct drm_gem_mm *mm = dev->mm_private;
-
 
325
	struct drm_map_list *list;
-
 
Line 326... Line 388...
326
	struct drm_local_map *map;
388
	struct drm_device *dev = obj->dev;
327
	int ret;
389
	struct drm_gem_mm *mm = dev->mm_private;
328
 
390
 
329
	/* Set the object up for mmap'ing */
391
	/* Set the object up for mmap'ing */
Line 437... Line 499...
437
 
499
 
438
	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
500
	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
439
	if (obj == NULL)
501
	if (obj == NULL)
Line -... Line 502...
-
 
502
		return -ENOENT;
440
		return -ENOENT;
503
 
441
 
504
	mutex_lock(&dev->object_name_lock);
-
 
505
	idr_preload(GFP_KERNEL);
-
 
506
	/* prevent races with concurrent gem_close. */
-
 
507
	if (obj->handle_count == 0) {
-
 
508
		ret = -ENOENT;
-
 
509
		goto err;
442
	idr_preload(GFP_KERNEL);
510
	}
443
	spin_lock(&dev->object_name_lock);
511
 
444
	if (!obj->name) {
512
	if (!obj->name) {
445
		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT);
513
		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT);
Line 454... Line 522...
454
 
522
 
455
		args->name = (uint64_t) obj->name;
523
		args->name = (uint64_t) obj->name;
Line 456... Line 524...
456
		ret = 0;
524
		ret = 0;
457
 
-
 
458
err:
525
 
-
 
526
err:
459
	spin_unlock(&dev->object_name_lock);
527
	idr_preload_end();
460
	idr_preload_end();
528
	mutex_unlock(&dev->object_name_lock);
461
	drm_gem_object_unreference_unlocked(obj);
529
	drm_gem_object_unreference_unlocked(obj);
Line 462... Line 530...
462
	return ret;
530
	return ret;
Line 481... Line 549...
481
		return -ENODEV;
549
		return -ENODEV;
Line 482... Line 550...
482
 
550
 
483
    if(handle == -2)
551
    if(handle == -2)
Line 484... Line 552...
484
        printf("%s handle %d\n", __FUNCTION__, handle);
552
        printf("%s handle %d\n", __FUNCTION__, handle);
485
 
553
 
486
	spin_lock(&dev->object_name_lock);
554
	mutex_lock(&dev->object_name_lock);
487
	obj = idr_find(&dev->object_name_idr, (int) args->name);
555
	obj = idr_find(&dev->object_name_idr, (int) args->name);
-
 
556
	if (obj) {
488
	if (obj)
557
		drm_gem_object_reference(obj);
489
		drm_gem_object_reference(obj);
-
 
490
	spin_unlock(&dev->object_name_lock);
558
	} else {
-
 
559
		mutex_unlock(&dev->object_name_lock);
Line -... Line 560...
-
 
560
		return -ENOENT;
491
	if (!obj)
561
	}
492
		return -ENOENT;
562
 
493
 
563
	/* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
494
	ret = drm_gem_handle_create(file_priv, obj, &handle);
564
	ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
Line 495... Line 565...
495
	drm_gem_object_unreference_unlocked(obj);
565
	drm_gem_object_unreference_unlocked(obj);
Line 523... Line 593...
523
	struct drm_file *file_priv = data;
593
	struct drm_file *file_priv = data;
524
	struct drm_gem_object *obj = ptr;
594
	struct drm_gem_object *obj = ptr;
525
	struct drm_device *dev = obj->dev;
595
	struct drm_device *dev = obj->dev;
Line 526... Line 596...
526
 
596
 
-
 
597
	drm_gem_remove_prime_handles(obj, file_priv);
Line 527... Line 598...
527
	drm_gem_remove_prime_handles(obj, file_priv);
598
	drm_vma_node_revoke(&obj->vma_node, file_priv->filp);
528
 
599
 
Line 529... Line 600...
529
	if (dev->driver->gem_close_object)
600
	if (dev->driver->gem_close_object)
Line 573... Line 644...
573
	if (dev->driver->gem_free_object != NULL)
644
	if (dev->driver->gem_free_object != NULL)
574
		dev->driver->gem_free_object(obj);
645
		dev->driver->gem_free_object(obj);
575
}
646
}
576
EXPORT_SYMBOL(drm_gem_object_free);
647
EXPORT_SYMBOL(drm_gem_object_free);
Line 577... Line -...
577
 
-
 
578
static void drm_gem_object_ref_bug(struct kref *list_kref)
-
 
579
{
-
 
580
	BUG();
-
 
581
}
-
 
582
 
-
 
583
/**
-
 
584
 * Called after the last handle to the object has been closed
-
 
585
 *
-
 
586
 * Removes any name for the object. Note that this must be
-
 
587
 * called before drm_gem_object_free or we'll be touching
-
 
588
 * freed memory
-
 
589
 */
-
 
590
void drm_gem_object_handle_free(struct drm_gem_object *obj)
-
 
591
{
-
 
592
	struct drm_device *dev = obj->dev;
-
 
593
 
-
 
594
	/* Remove any name for this object */
-
 
595
	spin_lock(&dev->object_name_lock);
-
 
596
	if (obj->name) {
-
 
597
		idr_remove(&dev->object_name_idr, obj->name);
-
 
598
		obj->name = 0;
-
 
599
		spin_unlock(&dev->object_name_lock);
-
 
600
		/*
-
 
601
		 * The object name held a reference to this object, drop
-
 
602
		 * that now.
-
 
603
		*
-
 
604
		* This cannot be the last reference, since the handle holds one too.
-
 
605
		 */
-
 
606
		kref_put(&obj->refcount, drm_gem_object_ref_bug);
-
 
607
	} else
-
 
608
		spin_unlock(&dev->object_name_lock);
-
 
609
 
-
 
610
}
-
 
Line 611... Line 648...
611
EXPORT_SYMBOL(drm_gem_object_handle_free);
648
 
612
 
649
 
613
#if 0
650
#if 0
614
void drm_gem_vm_open(struct vm_area_struct *vma)
651
void drm_gem_vm_open(struct vm_area_struct *vma)