From owner-freebsd-hackers Fri Oct 12 11:48:46 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by hub.freebsd.org (Postfix) with SMTP id 60BCE37B409 for ; Fri, 12 Oct 2001 11:48:40 -0700 (PDT) Received: (qmail 28055 invoked by uid 0); 12 Oct 2001 18:47:50 -0000 Received: from pd9e16bf0.dip.t-dialin.net (HELO forge.local) (217.225.107.240) by mail.gmx.net (mp020-rz3) with SMTP; 12 Oct 2001 18:47:50 -0000 Received: from tmm by forge.local with local (Exim 3.30 #1) id 15s7LG-000BiJ-00; Fri, 12 Oct 2001 20:47:31 +0200 Date: Fri, 12 Oct 2001 20:47:30 +0200 From: Thomas Moestl To: Matt Dillon Cc: Patrick Cipiere , tinguely@web.cs.ndsu.nodak.edu, freebsd-hackers@FreeBSD.ORG Subject: Re: contigfree, free what? Message-ID: <20011012204730.F407@crow.dom2ip.de> References: <200110121605.f9CG5F726010@ra.udcast.com> <200110121707.f9CH7Ax34395@earth.backplane.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="TakKZr9L6Hm6aLOc" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <200110121707.f9CH7Ax34395@earth.backplane.com>; from dillon@earth.backplane.com on Fri, Oct 12, 2001 at 10:07:10AM -0700 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --TakKZr9L6Hm6aLOc Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, 2001/10/12 at 10:07:10 -0700, Matt Dillon wrote: > > :Mark, > : > :> I also placed some checks on vm_map_delete > : > :I did that also, and as far as I understand everything works fine. > :The only thing I found was the fact that when contigmalloc() grabs the > :contig pages it sets the value of pga[i] (for i in allocated pages) > :note that: vm_page_t pga = vm_page_array; > : > :Then contigfree() does a pretty good job, but does not reset the values > :of pga[i] to pqtype == PQ_FREE (pqtype = pga[i].queue - pga[i].pc) > : > :So the next contigmalloc() requiring the same number of pages fails on > :the previously released pages because they are not PQ_FREE > : > :The other thing that puzzled me is the fact that in vm_map_delete() > :called by contgigfree() has a variable > :... I have also looked into this a while ago, but got stuck at some point. I have just looked at it again, and I think I have found a solution. > I think what is going on is that contigmalloc() is wiring the pages > but placing them in a pageable container (entry->wired_count == 0), > so when contigfree() kmem_free()'s the block the system does not know > that it must unwire the pages. This leaves the pages wired and prevents > them from being freed. > > I haven't found a quick and easy solution to the problem yet. kmem_alloc() > doesn't do what we want either. I tried calling vm_map_pageable() in > contigmalloc1() but it crashed the machine, so there might be something > else going on as well. This is probably because the map entries do have a NULL object pointer. vm_map_pageable() calls vm_fault_wire(), so this will fail. I have attached a patch which works for me. It duplicates most of the logic of kmem_alloc in that it calls vm_map_findspace() first, then vm_map_insert() (which basically is what is done in kmem_alloc_pageable() too, but here, kernel_object is passed instead of a NULL pointer, so that the map entry will have a valid object pointer). Then, the pages are inserted into the object as before, and finally, the map entries are marked as wired by using vm_map_pageable(). Because this will also call vm_fault_wire(), which will among other things do a vm_page_wire(), contigmalloc does not need to wire the pages itself. The pmap_kenter() calls can also be reomved, since the pages will be mapped in any case by vm_fault(). - thomas --TakKZr9L6Hm6aLOc Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="vm_contig.diff" --- vm_contig.c.orig Fri Oct 12 20:05:09 2001 +++ vm_contig.c Fri Oct 12 20:44:03 2001 @@ -76,6 +76,8 @@ #include #include #include +#include +#include #include #include #include @@ -232,7 +234,6 @@ m->busy = 0; m->queue = PQ_NONE; m->object = NULL; - vm_page_wire(m); } /* @@ -240,24 +241,31 @@ * Allocate kernel VM, unfree and assign the physical pages to it and * return kernel VM pointer. */ - tmp_addr = addr = kmem_alloc_pageable(map, size); - if (addr == 0) { + vm_map_lock(map); + if (vm_map_findspace(map, vm_map_min(map), size, &addr) != + KERN_SUCCESS) { /* * XXX We almost never run out of kernel virtual * space, so we don't make the allocated memory * above available. */ + vm_map_unlock(map); splx(s); return (NULL); } + vm_object_reference(kernel_object); + vm_map_insert(map, kernel_object, addr - VM_MIN_KERNEL_ADDRESS, + addr, addr + size, VM_PROT_ALL, VM_PROT_ALL, 0); + vm_map_unlock(map); + tmp_addr = addr; for (i = start; i < (start + size / PAGE_SIZE); i++) { vm_page_t m = &pga[i]; vm_page_insert(m, kernel_object, OFF_TO_IDX(tmp_addr - VM_MIN_KERNEL_ADDRESS)); - pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m)); tmp_addr += PAGE_SIZE; } + vm_map_pageable(map, addr, addr + size, FALSE); splx(s); return ((void *)addr); --TakKZr9L6Hm6aLOc-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message