DragonFly BSD
DragonFly submit List (threaded) for 2004-07
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

[PATCH] fix nvidia slowdowns and fix memleak in vm_map.c


From: Emiel Kollof <coolvibe@xxxxxxxxxxxxxxxx>
Date: Wed, 21 Jul 2004 00:01:20 +0200

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

(patches against sys/vm attached)

Discussion:

(From Christian Zander @ NVIDIA)

> The vm_map.c change just fixes a "hack" introduced in FreeBSD 4.7 to
> make it possible to use mmap(2) to map kernel memory, specifically to
> allow invalidation of cached physical addresses. If you could submit
> this for inclusion in the kernel, that'd be great.
> 
> The device pager leak was found by Tor Egge (of the FreeBSD project)
> and it was him who suggested the current workaround. I wrote/tested
> the patch, but you'd have to give him credit (I don't much care about
> credit as long as it works). I haven't heard back from him for some
> time, unfortunately, so I'm not sure when either of these patches is
> going to make its way into the FreeBSD kernel. If you can get a VM
> person to double-check the change, that'd be great; please CC me and
> Tor (tor.egge@xxxxxxxxxxxxxxxxxxxx, tegge@xxxxxxxxxxx).

So, if a vm-person (Matt?) could look at this, and mail/CC the people 
involved, that would be swell. And don't forget the attribution. :)

Cheers,
Emiel
- -- 
A Law of Computer Programming:
	Make it possible for programmers to write in English and you
will find the programmers cannot write in English.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (FreeBSD)

iD8DBQFA/ZYw4hAlCajuF/wRAgoVAJ4rr1l1P2qk6Tnin7eGypFY6Vrc8wCdEnkB
BDBZIRSRJDj8sYUy+gMDSdQ=
=Oikq
-----END PGP SIGNATURE-----
Index: device_pager.c
===================================================================
RCS file: /home/dcvs/src/sys/vm/device_pager.c,v
retrieving revision 1.7
diff -u -u -r1.7 device_pager.c
--- device_pager.c	23 Mar 2004 22:54:32 -0000	1.7
+++ device_pager.c	20 Jul 2004 22:21:39 -0000
@@ -70,6 +70,7 @@
 
 static vm_page_t dev_pager_getfake (vm_paddr_t);
 static void dev_pager_putfake (vm_page_t);
+static void dev_pager_updatefake (vm_page_t, vm_paddr_t);
 
 static int dev_pager_alloc_lock, dev_pager_alloc_lock_want;
 
@@ -194,18 +195,31 @@
 
 	paddr = pmap_phys_address(dev_dmmap(dev, (vm_offset_t) offset << PAGE_SHIFT, prot));
 	KASSERT(paddr != -1,("dev_pager_getpage: map function returns error"));
-	/*
-	 * Replace the passed in reqpage page with our own fake page and free up the
-	 * all of the original pages.
-	 */
-	page = dev_pager_getfake(paddr);
-	TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq);
-	for (i = 0; i < count; i++) {
-		vm_page_free(m[i]);
+
+	if ((m[reqpage]->flags & PG_FICTITIOUS) != 0) {
+		/*
+		 * If the passed in reqpage page is a fake page, update it with
+		 * the new physical address.
+		 */
+		dev_pager_updatefake(m[reqpage], paddr);
+		for (i = 0; i < count; i++) {
+			if (i != reqpage)
+				vm_page_free(m[i]);
+		}
+	} else {
+		/*
+		 * Replace the passed in reqpage page with our own fake page and
+		 * free up the all of the original pages.
+		 */
+		page = dev_pager_getfake(paddr);
+		TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq);
+		for (i = 0; i < count; i++) {
+			vm_page_free(m[i]);
+		}
+		s = splhigh();
+		vm_page_insert(page, object, offset);
+		splx(s);
 	}
-	s = splhigh();
-	vm_page_insert(page, object, offset);
-	splx(s);
 
 	return (VM_PAGER_OK);
 }
@@ -256,3 +270,11 @@
 		panic("dev_pager_putfake: bad page");
 	zfree(fakepg_zone, m);
 }
+
+static void
+dev_pager_updatefake(vm_page_t m, vm_paddr_t paddr)
+{
+	if (!(m->flags & PG_FICTITIOUS))
+		panic("dev_pager_putfake: bad page");
+	m->phys_addr = paddr;
+}
Index: vm_map.c
===================================================================
RCS file: /home/dcvs/src/sys/vm/vm_map.c,v
retrieving revision 1.28
diff -u -u -r1.28 vm_map.c
--- vm_map.c	27 May 2004 00:38:58 -0000	1.28
+++ vm_map.c	20 Jul 2004 22:21:46 -0000
@@ -2205,7 +2205,7 @@
 			vm_object_page_remove(object,
 			    OFF_TO_IDX(offset),
 			    OFF_TO_IDX(offset + size + PAGE_MASK),
-			    TRUE);
+			    (object->type == OBJT_DEVICE) ? FALSE : TRUE);
 			vm_object_deallocate(object);
 		}
 		start += size;


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]