Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 May 2006 17:20:09 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 96742 for review
Message-ID:  <200605061720.k46HK9EC031630@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=96742

Change 96742 by kmacy@kmacy_storage:sun4v_rwbuf on 2006/05/06 17:19:52

	clean up the semantics of tte_hash_lookup_inline
	assert that hash has no remaining entries in reset
	remove fragment pages allocated during process run in reset
	update membars in lock routines

Affected files ...

.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/tte_hash.c#22 edit

Differences ...

==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/tte_hash.c#22 (text+ko) ====

@@ -151,17 +151,20 @@
 	while (atomic_cmpset_long(&fields[0].tte.data, data, data | VTD_LOCK))
 		data = fields[0].tte.data & ~VTD_LOCK;
 
-	membar(StoreLoad);
+	membar(LoadLoad);
 		
 }
 
 static __inline void
 hash_bucket_unlock_inline(tte_hash_field_t fields) 
 {
+
+	membar(StoreStore|LoadStore);
 #ifdef DEBUG
 	if ((fields[0].tte.data & VTD_LOCK) == 0)
 		panic("trying to unlock bucket that isn't locked");
 #endif
+
 	fields[0].tte.data &= ~VTD_LOCK;
 	membar(StoreLoad);
 	spinlock_exit();
@@ -186,7 +189,6 @@
 	th->th_size = (size >> PAGE_SHIFT);
 	th->th_entries = 0;
 	th->th_context = 0;
-	printf("setting kernel hashtable to %lx\n", va);
 	th->th_hashtable = (tte_hash_entry_t)va;
 	
 	return th;
@@ -254,14 +256,17 @@
 	struct tte_hash_fragment *fh;
 	vm_page_t m;
 
-	for (fh = th->th_fhhead; fh != th->th_fhtail; fh = fh->thf_head.fh_next) {
+	for (fh = th->th_fhhead->thf_head.fh_next; fh != NULL; fh = fh->thf_head.fh_next) {
 		m = PHYS_TO_VM_PAGE((vm_paddr_t)TLB_DIRECT_TO_PHYS((vm_offset_t)fh));
 		m->wire_count--;
 		vm_page_free(m);
 	}
-	fh = th->th_fhhead = th->th_fhtail;
+	fh = th->th_fhtail = th->th_fhhead;
+	fh->thf_head.fh_next = NULL;
 	fh->thf_head.fh_count = 0; 
 	fh->thf_head.fh_free_head = 0;
+	if (th->th_entries != 0)
+		panic("%d remaining entries", th->th_entries);
 }
 
 static __inline void
@@ -291,11 +296,11 @@
 			if (m == NULL) 
 				VM_WAIT;
 		}
-		if (m->flags & PG_ZERO)
+		if ((m->flags & PG_ZERO) == 0)
 			pmap_zero_page(m);
 		fh->thf_head.fh_next = (void *)TLB_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(m));
 		fh = th->th_fhtail = (void *)TLB_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(m));
-		printf("allocating new fragment page fh=%p \n", fh);
+		printf("allocated new fragment page fh=%p \n", fh);
 
 	} 
 	newfield = fh->thf_entries[++fh->thf_head.fh_free_head].the_fields;
@@ -304,7 +309,7 @@
 	field->of.flags = TH_COLLISION;
 	field->of.next = newfield;
 
-	return (newfield);
+	return (&newfield[1]);
 }
 
 /*
@@ -312,13 +317,13 @@
  * and if field is non-null field will point to that entry
  * 
  * if no match is found 0 is returned and if field is non-null
- * and toappend is true field points to the first empty entry
- * allocating a new bucket if the current one is full
+ * field is set to the first empty entry or the last entry in a bucket
+ * 
  */
 
 
 static __inline tte_t 
-tte_hash_lookup_inline(tte_hash_t th, vm_offset_t va, tte_hash_field_t *field, int toappend)
+tte_hash_lookup_inline(tte_hash_t th, vm_offset_t va, tte_hash_field_t *field)
 {
 	uint64_t hash_shift, hash_index;
 	tte_hash_field_t fields;
@@ -343,11 +348,8 @@
 		if (fields[3].of.flags & TH_COLLISION) {
 			fields = fields[3].of.next;
 			goto retry;
-		} else if (toappend == TRUE) {
-			fields = tte_hash_allocate_fragment_entry(th, &fields[3]);
-			/* entry following shifted entry is the first unallocated */
-			i = 1;
 		} 
+		i = 3;
 	} 
 
 	if (field) 
@@ -407,7 +409,7 @@
 
 	hash_bucket_lock(fields);
 	
-	if ((tte_data = tte_hash_lookup_inline(th, va, &lookup_field, FALSE)) == 0) 
+	if ((tte_data = tte_hash_lookup_inline(th, va, &lookup_field)) == 0) 
 		goto done;
 
 	th->th_entries--;
@@ -446,7 +448,10 @@
 	tte_tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
 
 	hash_bucket_lock(fields);
-	otte_data = tte_hash_lookup_inline(th, va, &lookup_field, TRUE);
+	otte_data = tte_hash_lookup_inline(th, va, &lookup_field);
+	if (lookup_field->tte.tag != 0)
+		lookup_field = tte_hash_allocate_fragment_entry(th, lookup_field);
+	
 #ifdef DEBUG
 	if (otte_data)
 		panic("mapping for va=0x%lx already exists tte_data=0x%lx\n", va, otte_data);
@@ -462,7 +467,7 @@
 tte_t 
 tte_hash_lookup_nolock(tte_hash_t th, vm_offset_t va)
 {
-	return tte_hash_lookup_inline(th, va, NULL, FALSE);
+	return tte_hash_lookup_inline(th, va, NULL);
 }
 
 
@@ -485,7 +490,7 @@
 	fields = (th->th_hashtable[hash_index].the_fields);
 
 	hash_bucket_lock(fields);
-	tte_data = tte_hash_lookup_inline(th, va, NULL, FALSE);
+	tte_data = tte_hash_lookup_inline(th, va, NULL);
 	hash_bucket_unlock_inline(fields);
 	
 	return (tte_data);
@@ -536,8 +541,10 @@
 	fields = (th->th_hashtable[hash_index].the_fields);
 
 	hash_bucket_lock(fields);
-	otte_data = tte_hash_lookup_inline(th, va, &lookup_field, TRUE);
-	
+	otte_data = tte_hash_lookup_inline(th, va, &lookup_field);
+	if (otte_data == 0 && lookup_field->tte.tag != 0)
+		lookup_field = tte_hash_allocate_fragment_entry(th, lookup_field);
+
 	tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
 	
 	tte_hash_set_field(lookup_field, tag, tte_data);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605061720.k46HK9EC031630>