Be more aggressive in using superpages in all mappings of objects:
- Add a new address space allocation method (VMFS_OPTIMAL_SPACE) for vm_map_find() that will try to alter the alignment of a mapping to match any existing superpage mappings of the object being mapped. If no suitable address range is found with the necessary alignment, vm_map_find() will fall back to using the simple first-fit strategy (VMFS_ANY_SPACE). - Change mmap() without MAP_FIXED, shmat(), and the GEM mapping ioctl to use VMFS_OPTIMAL_SPACE instead of VMFS_ANY_SPACE. Reviewed by: alc (earlier version) MFC after: 2 weeks
This commit is contained in:
parent
748e404f26
commit
ff74a3fa6b
@ -1289,7 +1289,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
|||||||
vm_object_reference(obj->vm_obj);
|
vm_object_reference(obj->vm_obj);
|
||||||
DRM_UNLOCK(dev);
|
DRM_UNLOCK(dev);
|
||||||
rv = vm_map_find(map, obj->vm_obj, args->offset, &addr, args->size,
|
rv = vm_map_find(map, obj->vm_obj, args->offset, &addr, args->size,
|
||||||
VMFS_ANY_SPACE, VM_PROT_READ | VM_PROT_WRITE,
|
VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE,
|
||||||
VM_PROT_READ | VM_PROT_WRITE, MAP_SHARED);
|
VM_PROT_READ | VM_PROT_WRITE, MAP_SHARED);
|
||||||
if (rv != KERN_SUCCESS) {
|
if (rv != KERN_SUCCESS) {
|
||||||
vm_object_deallocate(obj->vm_obj);
|
vm_object_deallocate(obj->vm_obj);
|
||||||
|
@ -414,7 +414,7 @@ kern_shmat(td, shmid, shmaddr, shmflg)
|
|||||||
vm_object_reference(shmseg->object);
|
vm_object_reference(shmseg->object);
|
||||||
rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object,
|
rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object,
|
||||||
0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
|
0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
|
||||||
VMFS_ANY_SPACE, prot, prot, MAP_INHERIT_SHARE);
|
VMFS_OPTIMAL_SPACE, prot, prot, MAP_INHERIT_SHARE);
|
||||||
if (rv != KERN_SUCCESS) {
|
if (rv != KERN_SUCCESS) {
|
||||||
vm_object_deallocate(shmseg->object);
|
vm_object_deallocate(shmseg->object);
|
||||||
error = ENOMEM;
|
error = ENOMEM;
|
||||||
|
@ -1444,19 +1444,29 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
|||||||
vm_size_t length, int find_space, vm_prot_t prot,
|
vm_size_t length, int find_space, vm_prot_t prot,
|
||||||
vm_prot_t max, int cow)
|
vm_prot_t max, int cow)
|
||||||
{
|
{
|
||||||
vm_offset_t start;
|
vm_offset_t start, initial_addr;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
start = *addr;
|
if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL ||
|
||||||
|
(object->flags & OBJ_COLORED) == 0))
|
||||||
|
find_space = VMFS_ANY_SPACE;
|
||||||
|
initial_addr = *addr;
|
||||||
|
again:
|
||||||
|
start = initial_addr;
|
||||||
vm_map_lock(map);
|
vm_map_lock(map);
|
||||||
do {
|
do {
|
||||||
if (find_space != VMFS_NO_SPACE) {
|
if (find_space != VMFS_NO_SPACE) {
|
||||||
if (vm_map_findspace(map, start, length, addr)) {
|
if (vm_map_findspace(map, start, length, addr)) {
|
||||||
vm_map_unlock(map);
|
vm_map_unlock(map);
|
||||||
|
if (find_space == VMFS_OPTIMAL_SPACE) {
|
||||||
|
find_space = VMFS_ANY_SPACE;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
return (KERN_NO_SPACE);
|
return (KERN_NO_SPACE);
|
||||||
}
|
}
|
||||||
switch (find_space) {
|
switch (find_space) {
|
||||||
case VMFS_ALIGNED_SPACE:
|
case VMFS_ALIGNED_SPACE:
|
||||||
|
case VMFS_OPTIMAL_SPACE:
|
||||||
pmap_align_superpage(object, offset, addr,
|
pmap_align_superpage(object, offset, addr,
|
||||||
length);
|
length);
|
||||||
break;
|
break;
|
||||||
@ -1473,11 +1483,11 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
|||||||
}
|
}
|
||||||
result = vm_map_insert(map, object, offset, start, start +
|
result = vm_map_insert(map, object, offset, start, start +
|
||||||
length, prot, max, cow);
|
length, prot, max, cow);
|
||||||
} while (result == KERN_NO_SPACE && (find_space == VMFS_ALIGNED_SPACE
|
} while (result == KERN_NO_SPACE && (find_space == VMFS_ALIGNED_SPACE ||
|
||||||
#ifdef VMFS_TLB_ALIGNED_SPACE
|
#ifdef VMFS_TLB_ALIGNED_SPACE
|
||||||
|| find_space == VMFS_TLB_ALIGNED_SPACE
|
find_space == VMFS_TLB_ALIGNED_SPACE ||
|
||||||
#endif
|
#endif
|
||||||
));
|
find_space == VMFS_OPTIMAL_SPACE));
|
||||||
vm_map_unlock(map);
|
vm_map_unlock(map);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
@ -343,9 +343,10 @@ long vmspace_resident_count(struct vmspace *vmspace);
|
|||||||
*/
|
*/
|
||||||
#define VMFS_NO_SPACE 0 /* don't find; use the given range */
|
#define VMFS_NO_SPACE 0 /* don't find; use the given range */
|
||||||
#define VMFS_ANY_SPACE 1 /* find a range with any alignment */
|
#define VMFS_ANY_SPACE 1 /* find a range with any alignment */
|
||||||
#define VMFS_ALIGNED_SPACE 2 /* find a superpage-aligned range */
|
#define VMFS_OPTIMAL_SPACE 2 /* find a range with optimal alignment*/
|
||||||
|
#define VMFS_ALIGNED_SPACE 3 /* find a superpage-aligned range */
|
||||||
#if defined(__mips__)
|
#if defined(__mips__)
|
||||||
#define VMFS_TLB_ALIGNED_SPACE 3 /* find a TLB entry aligned range */
|
#define VMFS_TLB_ALIGNED_SPACE 4 /* find a TLB entry aligned range */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1603,7 +1603,8 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
|||||||
else if (fitit)
|
else if (fitit)
|
||||||
rv = vm_map_find(map, object, foff, addr, size,
|
rv = vm_map_find(map, object, foff, addr, size,
|
||||||
object != NULL && object->type == OBJT_DEVICE ?
|
object != NULL && object->type == OBJT_DEVICE ?
|
||||||
VMFS_ALIGNED_SPACE : VMFS_ANY_SPACE, prot, maxprot, docow);
|
VMFS_ALIGNED_SPACE : VMFS_OPTIMAL_SPACE, prot, maxprot,
|
||||||
|
docow);
|
||||||
else
|
else
|
||||||
rv = vm_map_fixed(map, object, foff, *addr, size,
|
rv = vm_map_fixed(map, object, foff, *addr, size,
|
||||||
prot, maxprot, docow);
|
prot, maxprot, docow);
|
||||||
|
Loading…
Reference in New Issue
Block a user