Skip to content

Commit 8afa13a

Browse files
committed
drm/vmwgfx: Implement DRIVER_GEM
This is initial change adding support for DRIVER_GEM to vmwgfx. vmwgfx was written before GEM and has always used TTM. Over the years the TTM buffers started inherting from GEM objects but vmwgfx never implemented GEM making it quite awkward. We were directly setting variables in GEM objects to not make DRM crash. This change brings vmwgfx inline with other DRM drivers and allows us to use a lot of DRM helpers which have depended on drivers with GEM support. Due to historical reasons vmwgfx splits the idea of a buffer and surface which makes it a littly tricky since either one can be used in most of our ioctl's which take user space handles. For now our BO's are GEM objects and our surfaces are opaque objects which are backed by GEM objects. In the future I'd like to combine those into a single BO but we don't want to break any of our existing ioctl's so it will take time to do it in a non-destructive way. Signed-off-by: Zack Rusin <[email protected]> Reviewed-by: Martin Krastev <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 8ad0c3f commit 8afa13a

25 files changed

+588
-745
lines changed

drivers/gpu/drm/vmwgfx/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ config DRM_VMWGFX
44
depends on DRM && PCI && MMU
55
depends on X86 || ARM64
66
select DRM_TTM
7+
select DRM_TTM_HELPER
78
select MAPPING_DIRTY_HELPERS
89
# Only needed for the transitional use of drm_crtc_init - can be removed
910
# again once vmwgfx sets up the primary plane itself.

drivers/gpu/drm/vmwgfx/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_hashtab.o vmwgfx_kms.o vmwgfx_d
99
vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
1010
vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \
1111
vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \
12-
vmwgfx_devcaps.o ttm_object.o vmwgfx_system_manager.o
12+
vmwgfx_devcaps.o ttm_object.o vmwgfx_system_manager.o \
13+
vmwgfx_gem.o
1314

1415
vmwgfx-$(CONFIG_DRM_FBDEV_EMULATION) += vmwgfx_fb.o
1516
vmwgfx-$(CONFIG_TRANSPARENT_HUGEPAGE) += vmwgfx_thp.o

drivers/gpu/drm/vmwgfx/ttm_object.c

Lines changed: 28 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include <linux/atomic.h>
5151
#include <linux/module.h>
5252
#include "ttm_object.h"
53+
#include "vmwgfx_drv.h"
5354

5455
MODULE_IMPORT_NS(DMA_BUF);
5556

@@ -73,7 +74,7 @@ struct ttm_object_file {
7374
struct ttm_object_device *tdev;
7475
spinlock_t lock;
7576
struct list_head ref_list;
76-
struct vmwgfx_open_hash ref_hash[TTM_REF_NUM];
77+
struct vmwgfx_open_hash ref_hash;
7778
struct kref refcount;
7879
};
7980

@@ -124,7 +125,6 @@ struct ttm_ref_object {
124125
struct vmwgfx_hash_item hash;
125126
struct list_head head;
126127
struct kref kref;
127-
enum ttm_ref_type ref_type;
128128
struct ttm_base_object *obj;
129129
struct ttm_object_file *tfile;
130130
};
@@ -160,17 +160,14 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
160160
struct ttm_base_object *base,
161161
bool shareable,
162162
enum ttm_object_type object_type,
163-
void (*refcount_release) (struct ttm_base_object **),
164-
void (*ref_obj_release) (struct ttm_base_object *,
165-
enum ttm_ref_type ref_type))
163+
void (*refcount_release) (struct ttm_base_object **))
166164
{
167165
struct ttm_object_device *tdev = tfile->tdev;
168166
int ret;
169167

170168
base->shareable = shareable;
171169
base->tfile = ttm_object_file_ref(tfile);
172170
base->refcount_release = refcount_release;
173-
base->ref_obj_release = ref_obj_release;
174171
base->object_type = object_type;
175172
kref_init(&base->refcount);
176173
idr_preload(GFP_KERNEL);
@@ -182,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
182179
return ret;
183180

184181
base->handle = ret;
185-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
182+
ret = ttm_ref_object_add(tfile, base, NULL, false);
186183
if (unlikely(ret != 0))
187184
goto out_err1;
188185

@@ -246,7 +243,7 @@ struct ttm_base_object *
246243
ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key)
247244
{
248245
struct vmwgfx_hash_item *hash;
249-
struct vmwgfx_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
246+
struct vmwgfx_open_hash *ht = &tfile->ref_hash;
250247
int ret;
251248

252249
rcu_read_lock();
@@ -266,7 +263,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
266263
{
267264
struct ttm_base_object *base = NULL;
268265
struct vmwgfx_hash_item *hash;
269-
struct vmwgfx_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
266+
struct vmwgfx_open_hash *ht = &tfile->ref_hash;
270267
int ret;
271268

272269
rcu_read_lock();
@@ -297,57 +294,12 @@ ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key)
297294
return base;
298295
}
299296

300-
/**
301-
* ttm_ref_object_exists - Check whether a caller has a valid ref object
302-
* (has opened) a base object.
303-
*
304-
* @tfile: Pointer to a struct ttm_object_file identifying the caller.
305-
* @base: Pointer to a struct base object.
306-
*
307-
* Checks wether the caller identified by @tfile has put a valid USAGE
308-
* reference object on the base object identified by @base.
309-
*/
310-
bool ttm_ref_object_exists(struct ttm_object_file *tfile,
311-
struct ttm_base_object *base)
312-
{
313-
struct vmwgfx_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
314-
struct vmwgfx_hash_item *hash;
315-
struct ttm_ref_object *ref;
316-
317-
rcu_read_lock();
318-
if (unlikely(vmwgfx_ht_find_item_rcu(ht, base->handle, &hash) != 0))
319-
goto out_false;
320-
321-
/*
322-
* Verify that the ref object is really pointing to our base object.
323-
* Our base object could actually be dead, and the ref object pointing
324-
* to another base object with the same handle.
325-
*/
326-
ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
327-
if (unlikely(base != ref->obj))
328-
goto out_false;
329-
330-
/*
331-
* Verify that the ref->obj pointer was actually valid!
332-
*/
333-
rmb();
334-
if (unlikely(kref_read(&ref->kref) == 0))
335-
goto out_false;
336-
337-
rcu_read_unlock();
338-
return true;
339-
340-
out_false:
341-
rcu_read_unlock();
342-
return false;
343-
}
344-
345297
int ttm_ref_object_add(struct ttm_object_file *tfile,
346298
struct ttm_base_object *base,
347-
enum ttm_ref_type ref_type, bool *existed,
299+
bool *existed,
348300
bool require_existed)
349301
{
350-
struct vmwgfx_open_hash *ht = &tfile->ref_hash[ref_type];
302+
struct vmwgfx_open_hash *ht = &tfile->ref_hash;
351303
struct ttm_ref_object *ref;
352304
struct vmwgfx_hash_item *hash;
353305
int ret = -EINVAL;
@@ -382,7 +334,6 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
382334
ref->hash.key = base->handle;
383335
ref->obj = base;
384336
ref->tfile = tfile;
385-
ref->ref_type = ref_type;
386337
kref_init(&ref->kref);
387338

388339
spin_lock(&tfile->lock);
@@ -411,27 +362,23 @@ ttm_ref_object_release(struct kref *kref)
411362
{
412363
struct ttm_ref_object *ref =
413364
container_of(kref, struct ttm_ref_object, kref);
414-
struct ttm_base_object *base = ref->obj;
415365
struct ttm_object_file *tfile = ref->tfile;
416366
struct vmwgfx_open_hash *ht;
417367

418-
ht = &tfile->ref_hash[ref->ref_type];
368+
ht = &tfile->ref_hash;
419369
(void)vmwgfx_ht_remove_item_rcu(ht, &ref->hash);
420370
list_del(&ref->head);
421371
spin_unlock(&tfile->lock);
422372

423-
if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release)
424-
base->ref_obj_release(base, ref->ref_type);
425-
426373
ttm_base_object_unref(&ref->obj);
427374
kfree_rcu(ref, rcu_head);
428375
spin_lock(&tfile->lock);
429376
}
430377

431378
int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
432-
unsigned long key, enum ttm_ref_type ref_type)
379+
unsigned long key)
433380
{
434-
struct vmwgfx_open_hash *ht = &tfile->ref_hash[ref_type];
381+
struct vmwgfx_open_hash *ht = &tfile->ref_hash;
435382
struct ttm_ref_object *ref;
436383
struct vmwgfx_hash_item *hash;
437384
int ret;
@@ -452,7 +399,6 @@ void ttm_object_file_release(struct ttm_object_file **p_tfile)
452399
{
453400
struct ttm_ref_object *ref;
454401
struct list_head *list;
455-
unsigned int i;
456402
struct ttm_object_file *tfile = *p_tfile;
457403

458404
*p_tfile = NULL;
@@ -470,8 +416,7 @@ void ttm_object_file_release(struct ttm_object_file **p_tfile)
470416
}
471417

472418
spin_unlock(&tfile->lock);
473-
for (i = 0; i < TTM_REF_NUM; ++i)
474-
vmwgfx_ht_remove(&tfile->ref_hash[i]);
419+
vmwgfx_ht_remove(&tfile->ref_hash);
475420

476421
ttm_object_file_unref(&tfile);
477422
}
@@ -480,8 +425,6 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
480425
unsigned int hash_order)
481426
{
482427
struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
483-
unsigned int i;
484-
unsigned int j = 0;
485428
int ret;
486429

487430
if (unlikely(tfile == NULL))
@@ -492,18 +435,13 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
492435
kref_init(&tfile->refcount);
493436
INIT_LIST_HEAD(&tfile->ref_list);
494437

495-
for (i = 0; i < TTM_REF_NUM; ++i) {
496-
ret = vmwgfx_ht_create(&tfile->ref_hash[i], hash_order);
497-
if (ret) {
498-
j = i;
499-
goto out_err;
500-
}
501-
}
438+
ret = vmwgfx_ht_create(&tfile->ref_hash, hash_order);
439+
if (ret)
440+
goto out_err;
502441

503442
return tfile;
504443
out_err:
505-
for (i = 0; i < j; ++i)
506-
vmwgfx_ht_remove(&tfile->ref_hash[i]);
444+
vmwgfx_ht_remove(&tfile->ref_hash);
507445

508446
kfree(tfile);
509447

@@ -526,7 +464,15 @@ ttm_object_device_init(unsigned int hash_order,
526464
if (ret != 0)
527465
goto out_no_object_hash;
528466

529-
idr_init_base(&tdev->idr, 1);
467+
/*
468+
* Our base is at VMWGFX_NUM_MOB + 1 because we want to create
469+
* a seperate namespace for GEM handles (which are
470+
* 1..VMWGFX_NUM_MOB) and the surface handles. Some ioctl's
471+
* can take either handle as an argument so we want to
472+
* easily be able to tell whether the handle refers to a
473+
* GEM buffer or a surface.
474+
*/
475+
idr_init_base(&tdev->idr, VMWGFX_NUM_MOB + 1);
530476
tdev->ops = *ops;
531477
tdev->dmabuf_release = tdev->ops.release;
532478
tdev->ops.release = ttm_prime_dmabuf_release;
@@ -647,7 +593,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
647593
prime = (struct ttm_prime_object *) dma_buf->priv;
648594
base = &prime->base;
649595
*handle = base->handle;
650-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
596+
ret = ttm_ref_object_add(tfile, base, NULL, false);
651597

652598
dma_buf_put(dma_buf);
653599

@@ -741,17 +687,14 @@ int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
741687
* @shareable: See ttm_base_object_init
742688
* @type: See ttm_base_object_init
743689
* @refcount_release: See ttm_base_object_init
744-
* @ref_obj_release: See ttm_base_object_init
745690
*
746691
* Initializes an object which is compatible with the drm_prime model
747692
* for data sharing between processes and devices.
748693
*/
749694
int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size,
750695
struct ttm_prime_object *prime, bool shareable,
751696
enum ttm_object_type type,
752-
void (*refcount_release) (struct ttm_base_object **),
753-
void (*ref_obj_release) (struct ttm_base_object *,
754-
enum ttm_ref_type ref_type))
697+
void (*refcount_release) (struct ttm_base_object **))
755698
{
756699
mutex_init(&prime->mutex);
757700
prime->size = PAGE_ALIGN(size);
@@ -760,6 +703,5 @@ int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size,
760703
prime->refcount_release = refcount_release;
761704
return ttm_base_object_init(tfile, &prime->base, shareable,
762705
ttm_prime_type,
763-
ttm_prime_refcount_release,
764-
ref_obj_release);
706+
ttm_prime_refcount_release);
765707
}

drivers/gpu/drm/vmwgfx/ttm_object.h

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,6 @@
4444

4545
#include "vmwgfx_hashtab.h"
4646

47-
/**
48-
* enum ttm_ref_type
49-
*
50-
* Describes what type of reference a ref object holds.
51-
*
52-
* TTM_REF_USAGE is a simple refcount on a base object.
53-
*
54-
* TTM_REF_SYNCCPU_READ is a SYNCCPU_READ reference on a
55-
* buffer object.
56-
*
57-
* TTM_REF_SYNCCPU_WRITE is a SYNCCPU_WRITE reference on a
58-
* buffer object.
59-
*
60-
*/
61-
62-
enum ttm_ref_type {
63-
TTM_REF_USAGE,
64-
TTM_REF_SYNCCPU_READ,
65-
TTM_REF_SYNCCPU_WRITE,
66-
TTM_REF_NUM
67-
};
68-
6947
/**
7048
* enum ttm_object_type
7149
*
@@ -76,7 +54,6 @@ enum ttm_ref_type {
7654

7755
enum ttm_object_type {
7856
ttm_fence_type,
79-
ttm_buffer_type,
8057
ttm_lock_type,
8158
ttm_prime_type,
8259
ttm_driver_type0 = 256,
@@ -127,8 +104,6 @@ struct ttm_base_object {
127104
struct ttm_object_file *tfile;
128105
struct kref refcount;
129106
void (*refcount_release) (struct ttm_base_object **base);
130-
void (*ref_obj_release) (struct ttm_base_object *base,
131-
enum ttm_ref_type ref_type);
132107
u32 handle;
133108
enum ttm_object_type object_type;
134109
u32 shareable;
@@ -177,11 +152,7 @@ extern int ttm_base_object_init(struct ttm_object_file *tfile,
177152
bool shareable,
178153
enum ttm_object_type type,
179154
void (*refcount_release) (struct ttm_base_object
180-
**),
181-
void (*ref_obj_release) (struct ttm_base_object
182-
*,
183-
enum ttm_ref_type
184-
ref_type));
155+
**));
185156

186157
/**
187158
* ttm_base_object_lookup
@@ -245,12 +216,9 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
245216
*/
246217
extern int ttm_ref_object_add(struct ttm_object_file *tfile,
247218
struct ttm_base_object *base,
248-
enum ttm_ref_type ref_type, bool *existed,
219+
bool *existed,
249220
bool require_existed);
250221

251-
extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
252-
struct ttm_base_object *base);
253-
254222
/**
255223
* ttm_ref_object_base_unref
256224
*
@@ -263,8 +231,7 @@ extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
263231
* will be unreferenced.
264232
*/
265233
extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
266-
unsigned long key,
267-
enum ttm_ref_type ref_type);
234+
unsigned long key);
268235

269236
/**
270237
* ttm_object_file_init - initialize a struct ttm_object file
@@ -328,10 +295,7 @@ extern int ttm_prime_object_init(struct ttm_object_file *tfile,
328295
bool shareable,
329296
enum ttm_object_type type,
330297
void (*refcount_release)
331-
(struct ttm_base_object **),
332-
void (*ref_obj_release)
333-
(struct ttm_base_object *,
334-
enum ttm_ref_type ref_type));
298+
(struct ttm_base_object **));
335299

336300
static inline enum ttm_object_type
337301
ttm_base_object_type(struct ttm_base_object *base)

0 commit comments

Comments
 (0)