Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drm: Some refactoring and bug fixes to address VM panics #2215

Merged
merged 11 commits into from
Oct 9, 2024
3 changes: 3 additions & 0 deletions sys/dev/drm/core/drm_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,20 +370,23 @@ static const struct vm_operations_struct drm_vm_ops = {
.fault = drm_vm_fault,
.open = drm_vm_open,
.close = drm_vm_close,
.objtype = OBJT_MGTDEVICE,
};

/** Shared virtual memory operations */
static const struct vm_operations_struct drm_vm_shm_ops = {
.fault = drm_vm_shm_fault,
.open = drm_vm_open,
.close = drm_vm_shm_close,
.objtype = OBJT_MGTDEVICE,
};

/** DMA virtual memory operations */
static const struct vm_operations_struct drm_vm_dma_ops = {
.fault = drm_vm_dma_fault,
.open = drm_vm_open,
.close = drm_vm_close,
.objtype = OBJT_MGTDEVICE,
};

/** Scatter-gather virtual memory operations */
Expand Down
12 changes: 5 additions & 7 deletions sys/dev/drm/drmkpi/include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,18 @@ struct vm_area_struct {
struct vm_fault {
unsigned int flags;
pgoff_t pgoff;
union {
/* user-space address */
void *virtual_address; /* < 4.11 */
unsigned long address; /* >= 4.11 */
};
vm_object_t object;
vm_pindex_t pindex; /* fault pindex */
int count; /* pages faulted in */
struct page *page;
struct vm_area_struct *vma;
};

struct vm_operations_struct {
void (*open) (struct vm_area_struct *);
void (*close) (struct vm_area_struct *);
int (*fault) (struct vm_area_struct *, struct vm_fault *);
int (*fault) (struct vm_fault *);
int (*access) (struct vm_area_struct *, unsigned long, void *, int, int);
int objtype;
};

struct sysinfo {
Expand Down
25 changes: 13 additions & 12 deletions sys/dev/drm/freebsd/drm_gem_cma_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,47 +156,47 @@ drm_gem_cma_alloc(struct drm_device *drm, struct drm_gem_cma_object *bo)
}

static int
drm_gem_cma_fault(struct vm_area_struct *dummy, struct vm_fault *vmf)
drm_gem_cma_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma;
struct drm_gem_object *gem_obj;
struct drm_gem_cma_object *bo;
vm_object_t obj;
vm_pindex_t pidx;
struct page *page;
int i;

vma = vmf->vma;
gem_obj = vma->vm_private_data;
obj = vmf->object;
gem_obj = obj->handle;
bo = container_of(gem_obj, struct drm_gem_cma_object, gem_obj);
obj = vma->vm_obj;

if (!bo->m)
return (VM_FAULT_SIGBUS);

pidx = OFF_TO_IDX(vmf->address - vma->vm_start);
pidx = vmf->pindex;
if (pidx >= bo->npages)
return (VM_FAULT_SIGBUS);

VM_OBJECT_WLOCK(obj);
for (i = 0; i < bo->npages; i++) {
page = bo->m[i];
if (vm_page_busied(page))
if (!vm_page_tryxbusy(page))
goto fail_unlock;
if (vm_page_insert(page, obj, i))
if (vm_page_insert(page, obj, i)) {
vm_page_xunbusy(page);
goto fail_unlock;
vm_page_tryxbusy(page);
}
page->valid = VM_PAGE_BITS_ALL;
}
VM_OBJECT_WUNLOCK(obj);

vma->vm_pfn_first = 0;
vma->vm_pfn_count = bo->npages;
DRM_DEBUG("%s: pidx: %llu, start: 0x%08X, addr: 0x%08lX\n", __func__, pidx, vma->vm_start, vmf->address);
vmf->pindex = 0;
vmf->count = bo->npages;

return (VM_FAULT_NOPAGE);

fail_unlock:
for (i--; i >= 0; i--)
vm_page_xunbusy(bo->m[i]);
VM_OBJECT_WUNLOCK(obj);
DRM_ERROR("%s: insert failed\n", __func__);
return (VM_FAULT_SIGBUS);
Expand All @@ -206,6 +206,7 @@ const struct vm_operations_struct drm_gem_cma_vm_ops = {
.fault = drm_gem_cma_fault,
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
.objtype = OBJT_MGTDEVICE,
};

static int
Expand Down
Loading
Loading