From owner-freebsd-hackers Mon Jan 29 15:28: 1 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from chopper.Poohsticks.ORG (chopper.poohsticks.org [63.227.60.73]) by hub.freebsd.org (Postfix) with ESMTP id B44DF37B404 for ; Mon, 29 Jan 2001 15:27:37 -0800 (PST) Received: from chopper.Poohsticks.ORG (drew@localhost.poohsticks.org [127.0.0.1]) by chopper.Poohsticks.ORG (8.10.1/8.10.1) with ESMTP id f0TNRbh22423 for ; Mon, 29 Jan 2001 16:27:37 -0700 Message-Id: <200101292327.f0TNRbh22423@chopper.Poohsticks.ORG> To: freebsd-hackers@freebsd.org Subject: Suboptimal mmap of devices on i86 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <22419.980810857.1@chopper.Poohsticks.ORG> Date: Mon, 29 Jan 2001 16:27:37 -0700 From: Drew Eckhardt Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On i86 boxes with 4M page capabilities, we want contiguous chunks of physical address space for mmaped devices to use those larger pages when possible. In practice, this doesn't happen in applications linked with shared libraries when mmap() is used in the usual way with 0 as the address argument and no MAP_FIXED flag. mmap() passes vm_mmap() a starting address after the heap. vm_mmap() adjusts this with pmap_addr_hint(), and the result propogates down to vm_map_findspace(). When there's insufficient free space to map the object at the optimally aligned address because a shared library is already there, vm_map_findspace() returns the first fit without adjusting the starting address. I tweaked my kernel as follows to get pmap_object_init_pt() functioning as designed. --- old Mon Jan 29 16:03:40 2001 +++ vm/vm_map.c Fri Jan 26 18:47:24 2001 @@ -169,6 +169,8 @@ static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t)); static void vm_map_split __P((vm_map_entry_t)); +static int vm_map_findspace_for_object __P((vm_map_t, vm_object_t, vm_offset_t, + vm_size_t, vm_offset_t *)); void vm_map_startup() @@ -775,10 +777,20 @@ /* * Find sufficient space for `length' bytes in the given map, starting at * `start'. The map must be locked. Returns 0 on success, 1 on no space. + * + * This differs from the stock vm_map_findspace() in that we have an + * additional parameter (object) which is used to get hints from the + * pmap layer which may result in stricter (coarser) alignment. + * + * FIXME: This should probably replace vm_map_findspace entirely. + * We may also want to revert to the historic behavior on failure, in the + * rare event that we have space for the requested region but not at the + * optimal alignment suggested by pmap_addr_hint(). */ -int -vm_map_findspace(map, start, length, addr) +static int +vm_map_findspace_for_object(map, object, start, length, addr) vm_map_t map; + vm_object_t object; vm_offset_t start; vm_size_t length; vm_offset_t *addr; @@ -811,6 +823,7 @@ * gap between existing regions, or after the very last region. */ for (;; start = (entry = next)->end) { + start = pmap_addr_hint(object, start, length); /* * Find the end of the proposed new region. Be sure we didn't * go beyond the end of the map, or wrap around the address; @@ -837,6 +850,21 @@ } /* + * Find sufficient space for `length' bytes in the given map, starting at + * `start'. The map must be locked. Returns 0 on success, 1 on no space. + */ +int +vm_map_findspace(map, start, length, addr) + vm_map_t map; + vm_offset_t start; + vm_size_t length; + vm_offset_t *addr; +{ + return (vm_map_findspace_for_object (map, NULL, start, length, + addr)); +} + +/* * vm_map_find finds an unallocated region in the target address * map with the given length. The search is defined to be * first-fit from the specified address; the region found is @@ -859,7 +887,8 @@ vm_map_lock(map); if (find_space) { - if (vm_map_findspace(map, start, length, addr)) { + if (vm_map_findspace_for_object(map, object, start, length, + addr)) { vm_map_unlock(map); if (map == kmem_map || map == mb_map) splx(s); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message