mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-20 11:40:20 +01:00
intel: Leak the userptr test bo
In order to use userptr, the kernel tracks the owner's mm with a mmu_notifier. Setting that is very expensive - it involves taking all mm_locks and a stop_machine(). This tracking lives only for as long as the client is using userptr objects - so if the client allocates then frees a userptr in a loop, we will be executing that heavyweight setup everytime. To ammoritize this cost, just leak the test bo and the single backing page we use for detecting userptr. v2: Free the object and memory when bufmgr is destroyed. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
This commit is contained in:
parent
9915e68b3b
commit
30921483c7
1 changed files with 28 additions and 11 deletions
|
|
@ -132,6 +132,11 @@ typedef struct _drm_intel_bufmgr_gem {
|
||||||
unsigned int has_vebox : 1;
|
unsigned int has_vebox : 1;
|
||||||
bool fenced_relocs;
|
bool fenced_relocs;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void *ptr;
|
||||||
|
uint32_t handle;
|
||||||
|
} userptr_active;
|
||||||
|
|
||||||
char *aub_filename;
|
char *aub_filename;
|
||||||
FILE *aub_file;
|
FILE *aub_file;
|
||||||
uint32_t aub_offset;
|
uint32_t aub_offset;
|
||||||
|
|
@ -943,7 +948,6 @@ has_userptr(drm_intel_bufmgr_gem *bufmgr_gem)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
long pgsz;
|
long pgsz;
|
||||||
struct drm_i915_gem_userptr userptr;
|
struct drm_i915_gem_userptr userptr;
|
||||||
struct drm_gem_close close_bo;
|
|
||||||
|
|
||||||
pgsz = sysconf(_SC_PAGESIZE);
|
pgsz = sysconf(_SC_PAGESIZE);
|
||||||
assert(pgsz > 0);
|
assert(pgsz > 0);
|
||||||
|
|
@ -970,15 +974,15 @@ retry:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memclear(close_bo);
|
/* We don't release the userptr bo here as we want to keep the
|
||||||
close_bo.handle = userptr.handle;
|
* kernel mm tracking alive for our lifetime. The first time we
|
||||||
ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
|
* create a userptr object the kernel has to install a mmu_notifer
|
||||||
free(ptr);
|
* which is a heavyweight operation (e.g. it requires taking all
|
||||||
if (ret) {
|
* mm_locks and stop_machine()).
|
||||||
fprintf(stderr, "Failed to release test userptr object! (%d) "
|
*/
|
||||||
"i915 kernel driver may not be sane!\n", errno);
|
|
||||||
return false;
|
bufmgr_gem->userptr_active.ptr = ptr;
|
||||||
}
|
bufmgr_gem->userptr_active.handle = userptr.handle;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1805,7 +1809,8 @@ static void
|
||||||
drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
|
drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
|
||||||
{
|
{
|
||||||
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
|
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
|
||||||
int i;
|
struct drm_gem_close close_bo;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
free(bufmgr_gem->exec2_objects);
|
free(bufmgr_gem->exec2_objects);
|
||||||
free(bufmgr_gem->exec_objects);
|
free(bufmgr_gem->exec_objects);
|
||||||
|
|
@ -1829,6 +1834,18 @@ drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release userptr bo kept hanging around for optimisation. */
|
||||||
|
if (bufmgr_gem->userptr_active.ptr) {
|
||||||
|
memclear(close_bo);
|
||||||
|
close_bo.handle = bufmgr_gem->userptr_active.handle;
|
||||||
|
ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
|
||||||
|
free(bufmgr_gem->userptr_active.ptr);
|
||||||
|
if (ret)
|
||||||
|
fprintf(stderr,
|
||||||
|
"Failed to release test userptr object! (%d) "
|
||||||
|
"i915 kernel driver may not be sane!\n", errno);
|
||||||
|
}
|
||||||
|
|
||||||
free(bufmgr);
|
free(bufmgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue