PERFORCE change 97395 for review
Kip Macy
kmacy at FreeBSD.org
Thu May 18 05:54:19 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=97395
Change 97395 by kmacy at kmacy_storage:sun4v_rwbuf on 2006/05/18 05:53:19
unlock bucket before panicking
do more exact tag matching in lookup
add more info to panic when invalid bit is set
Affected files ...
.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/tte_hash.c#30 edit
Differences ...
==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/tte_hash.c#30 (text+ko) ====
@@ -273,17 +273,20 @@
if (m == NULL)
VM_WAIT;
}
+#if 0
if ((m->flags & PG_ZERO) == 0)
+#endif
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("allocated new fragment page fh=%p \n", fh);
+ printf("new fh=%p \n", fh);
}
newfield = fh->thf_entries[++fh->thf_head.fh_free_head].the_fields;
+ bzero(newfield, sizeof(*newfield));
fh->thf_head.fh_count++;
- return (&newfield[0]);
+ return (newfield);
}
/*
@@ -297,26 +300,32 @@
static __inline tte_t
-tte_hash_lookup_inline(tte_hash_field_t fields, vm_offset_t va, boolean_t setfield)
+tte_hash_lookup_inline(tte_hash_field_t sfields, tte_t tte_tag, boolean_t setfield)
{
int i;
tte_t entry;
+ tte_hash_field_t fields;
- /* XXX - only handle 8K pages for now */
+ fields = sfields;
entry = 0;
-
retry:
for (i = 0; i < HASH_ENTRIES && fields[i].tte.tag != 0; i++) {
- if (((fields[i].tte.tag << TTARGET_VA_SHIFT) == (va & ~PAGE_MASK_4M))) {
+ if (tte_tag == fields[i].tte.tag) {
entry = (fields[i].tte.data & ~VTD_LOCK);
break;
}
}
if (i == HASH_ENTRIES) {
#ifdef DEBUG
- if (fields[(HASH_ENTRIES - 1)].of.flags & TH_INVALID)
- panic("invalid bit set");
+ if (fields[(HASH_ENTRIES - 1)].of.flags & TH_INVALID) {
+ hash_bucket_unlock(sfields, PSTATE_KERNEL);
+ printf("invalid bit set in lookup flags=0x%lx next=%p (sf=f):%d\n",
+ fields[(HASH_ENTRIES - 1)].of.flags,
+ fields[(HASH_ENTRIES - 1)].of.next,
+ (sfields==fields));
+ panic("bad flags");
+ }
#endif
if (fields[(HASH_ENTRIES - 1)].of.flags == TH_COLLISION) {
fields = fields[(HASH_ENTRIES - 1)].of.next;
@@ -325,9 +334,6 @@
i = (HASH_ENTRIES - 1);
}
- if (i >= HASH_ENTRIES)
- panic("invalid state");
-
if (setfield == TRUE)
PCPU_SET(lookup_field, (u_long)&fields[i]);
@@ -336,30 +342,36 @@
static __inline void
-tte_hash_lookup_last_inline(tte_hash_field_t fields, vm_offset_t va)
+tte_hash_lookup_last_inline(tte_hash_field_t sfields)
{
- int i, index;
- /* XXX - only handle 8K pages for now */
- index = -1;;
-
+ int i, depth;
+ tte_hash_field_t fields;
+
+ depth = 0;
+ fields = sfields;
retry:
for (i = 0; i < (HASH_ENTRIES - 1); i++)
- if (fields[i + 1].tte.tag == 0) {
- index = i;
+ if (fields[i + 1].tte.tag == 0)
break;
- }
- if (index != -1)
- PCPU_SET(last_field, (u_long)&fields[index]);
+ if (i < (HASH_ENTRIES - 1))
+ PCPU_SET(last_field, (u_long)&fields[i]);
else {
#ifdef DEBUG
- if (fields[(HASH_ENTRIES - 1)].of.flags & TH_INVALID)
- panic("invalid bit set");
+ if (fields[(HASH_ENTRIES - 1)].of.flags & TH_INVALID) {
+ hash_bucket_unlock(sfields, PSTATE_KERNEL);
+ printf("invalid bit set in lookup_last flags=0x%lx next=%p (sf=f):%d, depth=%d",
+ fields[(HASH_ENTRIES - 1)].of.flags,
+ fields[(HASH_ENTRIES - 1)].of.next,
+ (sfields==fields), depth);
+ panic("bad flags");
+ }
#endif
if (fields[(HASH_ENTRIES - 1)].of.flags == TH_COLLISION) {
if (fields[(HASH_ENTRIES - 1)].of.next[0].tte.tag != 0) {
fields = fields[(HASH_ENTRIES - 1)].of.next;
+ depth++;
goto retry;
} else {
/* 3rd entry is last */
@@ -379,15 +391,17 @@
{
uint64_t hash_shift, hash_index, s;
tte_hash_field_t fields;
- tte_t otte_data;
+ tte_t otte_data, tte_tag;
/* XXX - only handle 8K pages for now */
hash_shift = PAGE_SHIFT;
hash_index = (va >> hash_shift) & HASH_MASK(th);
fields = (th->th_hashtable[hash_index].the_fields);
+ tte_tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
+
s = hash_bucket_lock(fields);
- if((otte_data = tte_hash_lookup_inline(fields, va, TRUE)) != 0)
+ if((otte_data = tte_hash_lookup_inline(fields, tte_tag, TRUE)) != 0)
tte_hash_set_field((tte_hash_field_t)PCPU_GET(lookup_field),
((tte_hash_field_t)PCPU_GET(lookup_field))->tte.tag,
((tte_hash_field_t)PCPU_GET(lookup_field))->tte.data & ~flags);
@@ -402,20 +416,21 @@
{
uint64_t hash_shift, hash_index, s;
tte_hash_field_t fields;
- tte_t tte_data;
+ tte_t tte_data, tte_tag;
/* XXX - only handle 8K pages for now */
hash_shift = PAGE_SHIFT;
hash_index = (va >> hash_shift) & HASH_MASK(th);
fields = (th->th_hashtable[hash_index].the_fields);
+ tte_tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
s = hash_bucket_lock(fields);
- if ((tte_data = tte_hash_lookup_inline(fields, va, TRUE)) == 0)
+ if ((tte_data = tte_hash_lookup_inline(fields, tte_tag, TRUE)) == 0)
goto done;
- tte_hash_lookup_last_inline(fields, va);
+ tte_hash_lookup_last_inline(fields);
#ifdef DEBUG
if (((tte_hash_field_t)PCPU_GET(last_field))->tte.tag == 0) {
@@ -435,7 +450,10 @@
if (tte_data)
th->th_entries--;
-
+#ifdef DEBUG
+ if (tte_hash_lookup(th, va) != 0)
+ panic("tte_hash_delete failed");
+#endif
return (tte_data);
}
@@ -443,9 +461,9 @@
tte_hash_insert(tte_hash_t th, vm_offset_t va, tte_t tte_data)
{
- uint64_t hash_shift, hash_index, tte_tag, s;
+ uint64_t hash_shift, hash_index, s;
tte_hash_field_t fields, newfield;
- tte_t otte_data;
+ tte_t otte_data, tte_tag;
/* XXX - only handle 8K pages for now */
hash_shift = PAGE_SHIFT;
@@ -455,7 +473,13 @@
tte_tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
s = hash_bucket_lock(fields);
- otte_data = tte_hash_lookup_inline(fields, va, TRUE);
+ otte_data = tte_hash_lookup_inline(fields, tte_tag, TRUE);
+#ifdef DEBUG
+ if (otte_data) {
+ hash_bucket_unlock(fields, s);
+ panic("mapping for va=0x%lx already exists tte_data=0x%lx\n", va, otte_data);
+ }
+#endif
if (((tte_hash_field_t)PCPU_GET(lookup_field))->tte.tag != 0) {
hash_bucket_unlock(fields, s);
newfield = tte_hash_allocate_fragment_entry(th);
@@ -466,16 +490,17 @@
((tte_hash_field_t)PCPU_GET(lookup_field))->of.flags = TH_COLLISION;
((tte_hash_field_t)PCPU_GET(lookup_field))->of.next = newfield;
- otte_data = tte_hash_lookup_inline(fields, va, TRUE);
+ PCPU_SET(lookup_field, (u_long)&newfield[1]);
}
+ tte_hash_set_field((tte_hash_field_t)PCPU_GET(lookup_field), tte_tag, tte_data);
+
+ hash_bucket_unlock(fields, s);
#ifdef DEBUG
- if (otte_data)
- panic("mapping for va=0x%lx already exists tte_data=0x%lx\n", va, otte_data);
+ if (tte_hash_lookup(th, va) == 0)
+ panic("tte_hash_insert failed");
#endif
- tte_hash_set_field((tte_hash_field_t)PCPU_GET(lookup_field), tte_tag, tte_data);
- hash_bucket_unlock(fields, s);
th->th_entries++;
}
@@ -492,15 +517,17 @@
{
uint64_t hash_shift, hash_index, s;
tte_hash_field_t fields;
- tte_t tte_data;
+ tte_t tte_data, tte_tag;
/* XXX - only handle 8K pages for now */
hash_shift = PAGE_SHIFT;
hash_index = (va >> hash_shift) & HASH_MASK(th);
fields = (th->th_hashtable[hash_index].the_fields);
+ tte_tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
+
s = hash_bucket_lock(fields);
- tte_data = tte_hash_lookup_inline(fields, va, FALSE);
+ tte_data = tte_hash_lookup_inline(fields, tte_tag, FALSE);
hash_bucket_unlock(fields, s);
return (tte_data);
@@ -542,18 +569,18 @@
{
uint64_t hash_shift, hash_index;
tte_hash_field_t fields, newfield;
- tte_t otte_data;
- uint64_t tag, s;
+ tte_t otte_data, tte_tag;
+ uint64_t s;
/* XXX - only handle 8K pages for now */
hash_shift = PAGE_SHIFT;
hash_index = (va >> hash_shift) & HASH_MASK(th);
fields = (th->th_hashtable[hash_index].the_fields);
- tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
+ tte_tag = (((uint64_t)th->th_context << TTARGET_CTX_SHIFT)|(va >> TTARGET_VA_SHIFT));
s = hash_bucket_lock(fields);
- otte_data = tte_hash_lookup_inline(fields, va, TRUE);
+ otte_data = tte_hash_lookup_inline(fields, tte_tag, TRUE);
if (otte_data == 0 && ((tte_hash_field_t)PCPU_GET(lookup_field))->tte.tag != 0) {
hash_bucket_unlock(fields, s);
@@ -565,15 +592,19 @@
((tte_hash_field_t)PCPU_GET(lookup_field))->of.flags = TH_COLLISION;
((tte_hash_field_t)PCPU_GET(lookup_field))->of.next = newfield;
- otte_data = tte_hash_lookup_inline(fields, va, TRUE);
+ PCPU_SET(lookup_field, (u_long)&newfield[1]);
}
- tte_hash_set_field((tte_hash_field_t)PCPU_GET(lookup_field), tag, tte_data);
+ tte_hash_set_field((tte_hash_field_t)PCPU_GET(lookup_field), tte_tag, tte_data);
hash_bucket_unlock(fields, s);
if (otte_data == 0)
th->th_entries++;
+#ifdef DEBUG
+ if (tte_hash_lookup(th, va) == 0)
+ panic("tte_hash_update failed");
+#endif
return (otte_data);
}
More information about the p4-projects
mailing list