mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Change the logic for the default for MaxMemInQueues
If we can't detect the physical memory, the new default is 8 GB on 64-bit architectures, and 1 GB on 32-bit architectures. If we *can* detect the physical memory, the new default is CLAMP(256 MB, phys_mem * 0.75, MAX_DFLT) where MAX_DFLT is 8 GB on 64-bit architectures and 2 GB on 32-bit architectures. You can still override the default by hand. The logic here is simply trying to choose a lower default value on systems with less than 12 GB of physical RAM.
This commit is contained in:
parent
aca05fc5c0
commit
17ecd04fde
7
changes/bug11396
Normal file
7
changes/bug11396
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
o Minor features (security):
|
||||||
|
|
||||||
|
- If you don't specify MaxMemInQueues yourself, Tor now tries to
|
||||||
|
pick a good value based on your total system memory. Previously,
|
||||||
|
the default was always 8 GB. You can still override the default by
|
||||||
|
setting MaxMemInQueues yourself. Resolves ticket 11396.
|
||||||
|
|
@ -1752,7 +1752,8 @@ is non-zero):
|
|||||||
it has recovered at least 10% of this memory. Do not set this option too
|
it has recovered at least 10% of this memory. Do not set this option too
|
||||||
low, or your relay may be unreliable under load. This option only
|
low, or your relay may be unreliable under load. This option only
|
||||||
affects some queues, so the actual process size will be larger than
|
affects some queues, so the actual process size will be larger than
|
||||||
this. (Default: 8GB)
|
this. If this option is set to 0, Tor will try to pick a reasonable
|
||||||
|
default based on your system's physical memory. (Default: 0)
|
||||||
|
|
||||||
DIRECTORY SERVER OPTIONS
|
DIRECTORY SERVER OPTIONS
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -307,7 +307,7 @@ static config_var_t option_vars_[] = {
|
|||||||
V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
|
V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
|
||||||
V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
|
V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
|
||||||
V(MaxClientCircuitsPending, UINT, "32"),
|
V(MaxClientCircuitsPending, UINT, "32"),
|
||||||
V(MaxMemInQueues, MEMUNIT, "8 GB"),
|
VAR("MaxMeminQueues", MEMUNIT, MaxMemInQueues_raw, "0"),
|
||||||
OBSOLETE("MaxOnionsPending"),
|
OBSOLETE("MaxOnionsPending"),
|
||||||
V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
|
V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
|
||||||
V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"),
|
V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"),
|
||||||
@ -565,6 +565,8 @@ static void config_maybe_load_geoip_files_(const or_options_t *options,
|
|||||||
static int options_validate_cb(void *old_options, void *options,
|
static int options_validate_cb(void *old_options, void *options,
|
||||||
void *default_options,
|
void *default_options,
|
||||||
int from_setconf, char **msg);
|
int from_setconf, char **msg);
|
||||||
|
static uint64_t compute_real_max_mem_in_queues(const uint64_t val,
|
||||||
|
int log_guess);
|
||||||
|
|
||||||
/** Magic value for or_options_t. */
|
/** Magic value for or_options_t. */
|
||||||
#define OR_OPTIONS_MAGIC 9090909
|
#define OR_OPTIONS_MAGIC 9090909
|
||||||
@ -2793,11 +2795,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
REJECT("If EntryNodes is set, UseEntryGuards must be enabled.");
|
REJECT("If EntryNodes is set, UseEntryGuards must be enabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->MaxMemInQueues < (256 << 20)) {
|
options->MaxMemInQueues =
|
||||||
log_warn(LD_CONFIG, "MaxMemInQueues must be at least 256 MB for now. "
|
compute_real_max_mem_in_queues(options->MaxMemInQueues_raw,
|
||||||
"Ideally, have it as large as you can afford.");
|
server_mode(options));
|
||||||
options->MaxMemInQueues = (256 << 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
options->AllowInvalid_ = 0;
|
options->AllowInvalid_ = 0;
|
||||||
|
|
||||||
@ -3547,6 +3547,68 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
#undef COMPLAIN
|
#undef COMPLAIN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given the value that the user has set for MaxMemInQueues, compute the
|
||||||
|
* actual maximum value. We clip this value if it's too low, and autodetect
|
||||||
|
* it if it's set to 0. */
|
||||||
|
static uint64_t
|
||||||
|
compute_real_max_mem_in_queues(const uint64_t val, int log_guess)
|
||||||
|
{
|
||||||
|
uint64_t result;
|
||||||
|
|
||||||
|
if (val == 0) {
|
||||||
|
#define ONE_GIGABYTE (U64_LITERAL(1) << 30)
|
||||||
|
#define ONE_MEGABYTE (U64_LITERAL(1) << 20)
|
||||||
|
#if SIZEOF_VOID_P >= 8
|
||||||
|
#define MAX_DEFAULT_MAXMEM (8*ONE_GIGABYTE)
|
||||||
|
#else
|
||||||
|
#define MAX_DEFAULT_MAXMEM (2*ONE_GIGABYTE)
|
||||||
|
#endif
|
||||||
|
/* The user didn't pick a memory limit. Choose a very large one
|
||||||
|
* that is still smaller than the system memory */
|
||||||
|
static int notice_sent = 0;
|
||||||
|
size_t ram = 0;
|
||||||
|
if (get_total_system_memory(&ram) < 0) {
|
||||||
|
/* We couldn't determine our total system memory! */
|
||||||
|
#if SIZEOF_VOID_P >= 8
|
||||||
|
/* 64-bit system. Let's hope for 8 GB. */
|
||||||
|
result = 8 * ONE_GIGABYTE;
|
||||||
|
#else
|
||||||
|
/* (presumably) 32-bit system. Let's hope for 1 GB. */
|
||||||
|
result = ONE_GIGABYTE;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
/* We detected it, so let's pick 3/4 of the total RAM as our limit. */
|
||||||
|
const uint64_t avail = (ram / 4) * 3;
|
||||||
|
|
||||||
|
/* Make sure it's in range from 0.25 GB to 8 GB. */
|
||||||
|
if (avail > MAX_DEFAULT_MAXMEM) {
|
||||||
|
/* If you want to use more than this much RAM, you need to configure
|
||||||
|
it yourself */
|
||||||
|
result = MAX_DEFAULT_MAXMEM;
|
||||||
|
} else if (avail < ONE_GIGABYTE / 4) {
|
||||||
|
result = ONE_GIGABYTE / 4;
|
||||||
|
} else {
|
||||||
|
result = avail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (log_guess && ! notice_sent) {
|
||||||
|
log_notice(LD_CONFIG, "%sMaxMemInQueues is set to "U64_FORMAT" MB. "
|
||||||
|
"You can override this by setting MaxMemInQueues by hand.",
|
||||||
|
ram ? "Based on detected system memory, " : "",
|
||||||
|
U64_PRINTF_ARG(result / ONE_MEGABYTE));
|
||||||
|
notice_sent = 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else if (val < ONE_GIGABYTE / 4) {
|
||||||
|
log_warn(LD_CONFIG, "MaxMemInQueues must be at least 256 MB for now. "
|
||||||
|
"Ideally, have it as large as you can afford.");
|
||||||
|
return ONE_GIGABYTE / 4;
|
||||||
|
} else {
|
||||||
|
/* The value was fine all along */
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
|
/** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
|
||||||
* equal strings. */
|
* equal strings. */
|
||||||
static int
|
static int
|
||||||
|
@ -3474,7 +3474,10 @@ typedef struct {
|
|||||||
config_line_t *DirPort_lines;
|
config_line_t *DirPort_lines;
|
||||||
config_line_t *DNSPort_lines; /**< Ports to listen on for DNS requests. */
|
config_line_t *DNSPort_lines; /**< Ports to listen on for DNS requests. */
|
||||||
|
|
||||||
uint64_t MaxMemInQueues; /**< If we have more memory than this allocated
|
/* MaxMemInQueues value as input by the user. We clean this up to be
|
||||||
|
* MaxMemInQueues. */
|
||||||
|
uint64_t MaxMemInQueues_raw;
|
||||||
|
uint64_t MaxMemInQueues;/**< If we have more memory than this allocated
|
||||||
* for queues and buffers, run the OOM handler */
|
* for queues and buffers, run the OOM handler */
|
||||||
|
|
||||||
/** @name port booleans
|
/** @name port booleans
|
||||||
|
Loading…
Reference in New Issue
Block a user