Skip to content

Commit cf3e3e8

Browse files
committed
drm/i915: Use ttm mmap handling for ttm bo's.
Use the ttm handlers for servicing page faults, and vm_access. We do our own validation of read-only access, otherwise use the ttm handlers as much as possible. Because the ttm handlers expect the vma_node at vma->base, we slightly need to massage the mmap handlers to look at vma_node->driver_private to fetch the bo, if it's NULL, we assume i915's normal mmap_offset uapi is used. This is the easiest way to achieve compatibility without changing ttm's semantics. Signed-off-by: Maarten Lankhorst <[email protected]> Reviewed-by: Thomas Hellström <[email protected]> Signed-off-by: Maarten Lankhorst <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent f425821 commit cf3e3e8

File tree

8 files changed

+251
-92
lines changed

8 files changed

+251
-92
lines changed

drivers/gpu/drm/i915/gem/i915_gem_mman.c

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "i915_gem_mman.h"
2020
#include "i915_trace.h"
2121
#include "i915_user_extensions.h"
22+
#include "i915_gem_ttm.h"
2223
#include "i915_vma.h"
2324

2425
static inline bool
@@ -623,6 +624,8 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
623624
struct i915_mmap_offset *mmo;
624625
int err;
625626

627+
GEM_BUG_ON(obj->ops->mmap_offset || obj->ops->mmap_ops);
628+
626629
mmo = lookup_mmo(obj, mmap_type);
627630
if (mmo)
628631
goto out;
@@ -665,40 +668,47 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
665668
}
666669

667670
static int
668-
__assign_mmap_offset(struct drm_file *file,
669-
u32 handle,
671+
__assign_mmap_offset(struct drm_i915_gem_object *obj,
670672
enum i915_mmap_type mmap_type,
671-
u64 *offset)
673+
u64 *offset, struct drm_file *file)
672674
{
673-
struct drm_i915_gem_object *obj;
674675
struct i915_mmap_offset *mmo;
675-
int err;
676676

677-
obj = i915_gem_object_lookup(file, handle);
678-
if (!obj)
679-
return -ENOENT;
677+
if (i915_gem_object_never_mmap(obj))
678+
return -ENODEV;
680679

681-
if (i915_gem_object_never_mmap(obj)) {
682-
err = -ENODEV;
683-
goto out;
680+
if (obj->ops->mmap_offset) {
681+
*offset = obj->ops->mmap_offset(obj);
682+
return 0;
684683
}
685684

686685
if (mmap_type != I915_MMAP_TYPE_GTT &&
687686
!i915_gem_object_has_struct_page(obj) &&
688-
!i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM)) {
689-
err = -ENODEV;
690-
goto out;
691-
}
687+
!i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
688+
return -ENODEV;
692689

693690
mmo = mmap_offset_attach(obj, mmap_type, file);
694-
if (IS_ERR(mmo)) {
695-
err = PTR_ERR(mmo);
696-
goto out;
697-
}
691+
if (IS_ERR(mmo))
692+
return PTR_ERR(mmo);
698693

699694
*offset = drm_vma_node_offset_addr(&mmo->vma_node);
700-
err = 0;
701-
out:
695+
return 0;
696+
}
697+
698+
static int
699+
__assign_mmap_offset_handle(struct drm_file *file,
700+
u32 handle,
701+
enum i915_mmap_type mmap_type,
702+
u64 *offset)
703+
{
704+
struct drm_i915_gem_object *obj;
705+
int err;
706+
707+
obj = i915_gem_object_lookup(file, handle);
708+
if (!obj)
709+
return -ENOENT;
710+
711+
err = __assign_mmap_offset(obj, mmap_type, offset, file);
702712
i915_gem_object_put(obj);
703713
return err;
704714
}
@@ -718,7 +728,7 @@ i915_gem_dumb_mmap_offset(struct drm_file *file,
718728
else
719729
mmap_type = I915_MMAP_TYPE_GTT;
720730

721-
return __assign_mmap_offset(file, handle, mmap_type, offset);
731+
return __assign_mmap_offset_handle(file, handle, mmap_type, offset);
722732
}
723733

724734
/**
@@ -786,7 +796,7 @@ i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
786796
return -EINVAL;
787797
}
788798

789-
return __assign_mmap_offset(file, args->handle, type, &args->offset);
799+
return __assign_mmap_offset_handle(file, args->handle, type, &args->offset);
790800
}
791801

792802
static void vm_open(struct vm_area_struct *vma)
@@ -890,8 +900,18 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
890900
* destroyed and will be invalid when the vma manager lock
891901
* is released.
892902
*/
893-
mmo = container_of(node, struct i915_mmap_offset, vma_node);
894-
obj = i915_gem_object_get_rcu(mmo->obj);
903+
if (!node->driver_private) {
904+
mmo = container_of(node, struct i915_mmap_offset, vma_node);
905+
obj = i915_gem_object_get_rcu(mmo->obj);
906+
907+
GEM_BUG_ON(obj && obj->ops->mmap_ops);
908+
} else {
909+
obj = i915_gem_object_get_rcu
910+
(container_of(node, struct drm_i915_gem_object,
911+
base.vma_node));
912+
913+
GEM_BUG_ON(obj && !obj->ops->mmap_ops);
914+
}
895915
}
896916
drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
897917
rcu_read_unlock();
@@ -913,7 +933,9 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
913933
}
914934

915935
vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
916-
vma->vm_private_data = mmo;
936+
937+
if (i915_gem_object_has_iomem(obj))
938+
vma->vm_flags |= VM_IO;
917939

918940
/*
919941
* We keep the ref on mmo->obj, not vm_file, but we require
@@ -927,6 +949,15 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
927949
/* Drop the initial creation reference, the vma is now holding one. */
928950
fput(anon);
929951

952+
if (obj->ops->mmap_ops) {
953+
vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags));
954+
vma->vm_ops = obj->ops->mmap_ops;
955+
vma->vm_private_data = node->driver_private;
956+
return 0;
957+
}
958+
959+
vma->vm_private_data = mmo;
960+
930961
switch (mmo->mmap_type) {
931962
case I915_MMAP_TYPE_WC:
932963
vma->vm_page_prot =

drivers/gpu/drm/i915/gem/i915_gem_object.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,22 +342,22 @@ struct scatterlist *
342342
__i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
343343
struct i915_gem_object_page_iter *iter,
344344
unsigned int n,
345-
unsigned int *offset, bool allow_alloc);
345+
unsigned int *offset, bool allow_alloc, bool dma);
346346

347347
static inline struct scatterlist *
348348
i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
349349
unsigned int n,
350350
unsigned int *offset, bool allow_alloc)
351351
{
352-
return __i915_gem_object_get_sg(obj, &obj->mm.get_page, n, offset, allow_alloc);
352+
return __i915_gem_object_get_sg(obj, &obj->mm.get_page, n, offset, allow_alloc, false);
353353
}
354354

355355
static inline struct scatterlist *
356356
i915_gem_object_get_sg_dma(struct drm_i915_gem_object *obj,
357357
unsigned int n,
358358
unsigned int *offset, bool allow_alloc)
359359
{
360-
return __i915_gem_object_get_sg(obj, &obj->mm.get_dma_page, n, offset, allow_alloc);
360+
return __i915_gem_object_get_sg(obj, &obj->mm.get_dma_page, n, offset, allow_alloc, true);
361361
}
362362

363363
struct page *

drivers/gpu/drm/i915/gem/i915_gem_object_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct drm_i915_gem_object_ops {
6161
const struct drm_i915_gem_pread *arg);
6262
int (*pwrite)(struct drm_i915_gem_object *obj,
6363
const struct drm_i915_gem_pwrite *arg);
64+
u64 (*mmap_offset)(struct drm_i915_gem_object *obj);
6465

6566
int (*dmabuf_export)(struct drm_i915_gem_object *obj);
6667

@@ -79,6 +80,7 @@ struct drm_i915_gem_object_ops {
7980
void (*delayed_free)(struct drm_i915_gem_object *obj);
8081
void (*release)(struct drm_i915_gem_object *obj);
8182

83+
const struct vm_operations_struct *mmap_ops;
8284
const char *name; /* friendly name for debug, e.g. lockdep classes */
8385
};
8486

@@ -328,6 +330,7 @@ struct drm_i915_gem_object {
328330

329331
struct {
330332
struct sg_table *cached_io_st;
333+
struct i915_gem_object_page_iter get_io_page;
331334
bool created:1;
332335
} ttm;
333336

drivers/gpu/drm/i915/gem/i915_gem_pages.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,8 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
467467
struct i915_gem_object_page_iter *iter,
468468
unsigned int n,
469469
unsigned int *offset,
470-
bool allow_alloc)
470+
bool allow_alloc, bool dma)
471471
{
472-
const bool dma = iter == &obj->mm.get_dma_page;
473472
struct scatterlist *sg;
474473
unsigned int idx, count;
475474

0 commit comments

Comments
 (0)