Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161955027
D57793.id180636.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D57793.id180636.diff
View Options
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -419,19 +419,16 @@
SYSCTL_ULONG(_debug_witness, OID_AUTO, witness_count,
CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &witness_count, 0,
"Maximum count of lock type entries");
-TUNABLE_ULONG("debug.witness.witness_count", &witness_count);
static u_long witness_lo_data_count = WITNESS_LO_DATA_COUNT;
SYSCTL_ULONG(_debug_witness, OID_AUTO, lock_order_data_count,
CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &witness_lo_data_count, 0,
"Maximum count of lock order data (stacks) to track");
-TUNABLE_ULONG("debug.witness.lock_order_data_count", &witness_lo_data_count);
static u_long witness_lo_hash_size = WITNESS_LO_HASH_SIZE;
SYSCTL_ULONG(_debug_witness, OID_AUTO, lock_order_hash_size,
CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &witness_lo_hash_size, 0,
"Hash table size for lock order data");
-TUNABLE_ULONG("debug.witness.lock_order_hash_size", &witness_lo_hash_size);
/*
* Output channel for witness messages. By default we print to the console.
@@ -489,6 +486,7 @@
static uint8_t **w_rmatrix;
static struct lock_list_entry w_locklistdata[LOCK_CHILDCOUNT];
static struct witness_hash w_hash; /* The witness hash table. */
+static u_long w_sz; /* Witness startup memory allocation size */
/* The lock order data hash */
static struct witness_lock_order_data *w_lodata;
@@ -791,10 +789,10 @@
/*
* Calculate the size of early witness structures.
*/
-int
-witness_startup_count(void)
+static u_long
+witness_startup_calc(void)
{
- int sz;
+ u_long sz;
sz = sizeof(struct witness) * witness_count;
sz += sizeof(*w_rmatrix) * (witness_count + 1);
@@ -803,10 +801,55 @@
sz += sizeof(void *);
sz += sizeof(w_lodata[0]) * witness_lo_data_count;
sz += sizeof(w_lohash.wloh_array[0]) * witness_lo_hash_size;
+ sz = round_page(sz);
return (sz);
}
+u_long
+witness_startup_count(u_long avail)
+{
+
+ /* Tune witness. */
+ TUNABLE_ULONG_FETCH("debug.witness.witness_count", &witness_count);
+ witness_count = ulmax(witness_count, 1);
+ TUNABLE_ULONG_FETCH("debug.witness.lock_order_data_count",
+ &witness_lo_data_count);
+ TUNABLE_ULONG_FETCH("debug.witness.lock_order_hash_size",
+ &witness_lo_hash_size);
+ w_sz = witness_startup_calc();
+ if (w_sz <= avail)
+ return (w_sz);
+
+ /* Memory allocation would be too large, try fallbacks. */
+ printf("WARNING: WITNESS configuration would need %lu KiB, "
+ "with %lu KiB available\n", w_sz / 1024, avail / 1024);
+ witness_count = ulmin(witness_count, WITNESS_COUNT);
+ witness_lo_data_count = ulmin(witness_lo_data_count,
+ WITNESS_LO_DATA_COUNT);
+ witness_lo_hash_size = ulmin(witness_lo_hash_size,
+ WITNESS_LO_HASH_SIZE);
+ w_sz = witness_startup_calc();
+ if (w_sz <= avail) {
+ printf("WARNING: WITNESS configuration reduced to defaults\n");
+ return (w_sz);
+ }
+
+ /* Minimize startup allocations, functionally disabling witness. */
+ witness_count = 1;
+ witness_lo_data_count = 0;
+ witness_lo_hash_size = 1;
+ w_sz = witness_startup_calc();
+ if (w_sz <= avail) {
+ printf("WARNING: WITNESS configuration defaults too large, "
+ "lock order checks disabled\n");
+ return (w_sz);
+ }
+
+ panic("WITNESS unable to initialize with %lu KiB available",
+ avail / 1024);
+}
+
/*
* The WITNESS-enabled diagnostic code. Note that the witness code does
* assume that the early boot is single-threaded at least until after this
@@ -843,6 +886,8 @@
w_lohash.wloh_array = (void *)p;
p += sizeof(w_lohash.wloh_array[0]) * witness_lo_hash_size;
+ MPASS(p <= (uintptr_t)mem + w_sz);
+
badstack_sbuf_size = witness_count * 256;
/*
diff --git a/sys/sys/lock.h b/sys/sys/lock.h
--- a/sys/sys/lock.h
+++ b/sys/sys/lock.h
@@ -247,7 +247,7 @@
void witness_thread_exit(struct thread *);
#ifdef WITNESS
-int witness_startup_count(void);
+u_long witness_startup_count(u_long);
void witness_startup(void *);
/* Flags for witness_warn(). */
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -585,7 +585,7 @@
int biggestone, i, segind;
#ifdef WITNESS
void *mapped;
- int witness_size;
+ u_long witness_size;
#endif
#if defined(__i386__) && defined(VM_PHYSSEG_DENSE)
long ii;
@@ -610,7 +610,14 @@
new_end = end;
#ifdef WITNESS
- witness_size = round_page(witness_startup_count());
+ /*
+ * witness(4) support. Allocate and map memory and initialize.
+ * Advertised available memory is limited in order to avoid witness
+ * misconfiguration consuming memory needed for subsequent essential
+ * allocations.
+ */
+ witness_size = round_page(witness_startup_count(
+ trunc_page((new_end - phys_avail[biggestone]) / 2)));
new_end -= witness_size;
mapped = pmap_map(&vaddr, new_end, new_end + witness_size,
VM_PROT_READ | VM_PROT_WRITE);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 9, 8:11 AM (17 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34881806
Default Alt Text
D57793.id180636.diff (4 KB)
Attached To
Mode
D57793: witness: harden tunables for large settings
Attached
Detach File
Event Timeline
Log In to Comment