aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/or/circuitlist.c12
-rw-r--r--src/core/or/circuitlist.h2
-rw-r--r--src/core/or/relay.c22
-rw-r--r--src/core/or/relay.h5
4 files changed, 31 insertions, 10 deletions
diff --git a/src/core/or/circuitlist.c b/src/core/or/circuitlist.c
index 4f62284e29..46be358dec 100644
--- a/src/core/or/circuitlist.c
+++ b/src/core/or/circuitlist.c
@@ -2586,8 +2586,10 @@ conns_compare_by_buffer_age_(const void **a_, const void **b_)
/** We're out of memory for cells, having allocated <b>current_allocation</b>
* bytes' worth. Kill the 'worst' circuits until we're under
- * FRACTION_OF_DATA_TO_RETAIN_ON_OOM of our maximum usage. */
-void
+ * FRACTION_OF_DATA_TO_RETAIN_ON_OOM of our maximum usage.
+ *
+ * Return the number of bytes removed. */
+size_t
circuits_handle_oom(size_t current_allocation)
{
smartlist_t *circlist;
@@ -2613,12 +2615,11 @@ circuits_handle_oom(size_t current_allocation)
tor_zstd_get_total_allocation(),
tor_lzma_get_total_allocation(),
hs_cache_get_total_allocation());
-
{
size_t mem_target = (size_t)(get_options()->MaxMemInQueues *
FRACTION_OF_DATA_TO_RETAIN_ON_OOM);
if (current_allocation <= mem_target)
- return;
+ return 0;
mem_to_recover = current_allocation - mem_target;
}
@@ -2697,7 +2698,6 @@ circuits_handle_oom(size_t current_allocation)
} SMARTLIST_FOREACH_END(circ);
done_recovering_mem:
-
log_notice(LD_GENERAL, "Removed %"TOR_PRIuSZ" bytes by killing %d circuits; "
"%d circuits remain alive. Also killed %d non-linked directory "
"connections.",
@@ -2705,6 +2705,8 @@ circuits_handle_oom(size_t current_allocation)
n_circuits_killed,
smartlist_len(circlist) - n_circuits_killed,
n_dirconns_killed);
+
+ return mem_recovered;
}
/** Verify that circuit <b>c</b> has all of its invariants
diff --git a/src/core/or/circuitlist.h b/src/core/or/circuitlist.h
index f5791d7c12..147e2cb2f8 100644
--- a/src/core/or/circuitlist.h
+++ b/src/core/or/circuitlist.h
@@ -232,7 +232,7 @@ int circuit_count_pending_on_channel(channel_t *chan);
MOCK_DECL(void, assert_circuit_ok,(const circuit_t *c));
void circuit_free_all(void);
-void circuits_handle_oom(size_t current_allocation);
+size_t circuits_handle_oom(size_t current_allocation);
void circuit_clear_testing_cell_stats(circuit_t *circ);
diff --git a/src/core/or/relay.c b/src/core/or/relay.c
index 2248b2c180..7e1f1dc43d 100644
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@ -2701,11 +2701,18 @@ cell_queues_get_total_allocation(void)
/** The time at which we were last low on memory. */
static time_t last_time_under_memory_pressure = 0;
+/** Statistics on how many bytes were removed by the OOM per type. */
+uint64_t oom_stats_n_bytes_removed_dns = 0;
+uint64_t oom_stats_n_bytes_removed_cell = 0;
+uint64_t oom_stats_n_bytes_removed_geoip = 0;
+uint64_t oom_stats_n_bytes_removed_hsdir = 0;
+
/** Check whether we've got too much space used for cells. If so,
* call the OOM handler and return 1. Otherwise, return 0. */
STATIC int
cell_queues_check_size(void)
{
+ size_t removed = 0;
time_t now = time(NULL);
size_t alloc = cell_queues_get_total_allocation();
alloc += half_streams_get_total_allocation();
@@ -2730,20 +2737,27 @@ cell_queues_check_size(void)
if (hs_cache_total > get_options()->MaxMemInQueues / 5) {
const size_t bytes_to_remove =
hs_cache_total - (size_t)(get_options()->MaxMemInQueues / 10);
- alloc -= hs_cache_handle_oom(now, bytes_to_remove);
+ removed = hs_cache_handle_oom(now, bytes_to_remove);
+ oom_stats_n_bytes_removed_hsdir += removed;
+ alloc -= removed;
}
if (geoip_client_cache_total > get_options()->MaxMemInQueues / 5) {
const size_t bytes_to_remove =
geoip_client_cache_total -
(size_t)(get_options()->MaxMemInQueues / 10);
- alloc -= geoip_client_cache_handle_oom(now, bytes_to_remove);
+ removed = geoip_client_cache_handle_oom(now, bytes_to_remove);
+ oom_stats_n_bytes_removed_geoip += removed;
+ alloc -= removed;
}
if (dns_cache_total > get_options()->MaxMemInQueues / 5) {
const size_t bytes_to_remove =
dns_cache_total - (size_t)(get_options()->MaxMemInQueues / 10);
- alloc -= dns_cache_handle_oom(now, bytes_to_remove);
+ removed = dns_cache_handle_oom(now, bytes_to_remove);
+ oom_stats_n_bytes_removed_dns += removed;
+ alloc -= removed;
}
- circuits_handle_oom(alloc);
+ removed = circuits_handle_oom(alloc);
+ oom_stats_n_bytes_removed_cell += removed;
return 1;
}
}
diff --git a/src/core/or/relay.h b/src/core/or/relay.h
index 2f337d5d16..eac920f491 100644
--- a/src/core/or/relay.h
+++ b/src/core/or/relay.h
@@ -49,6 +49,11 @@ extern uint64_t stats_n_data_bytes_packaged;
extern uint64_t stats_n_data_cells_received;
extern uint64_t stats_n_data_bytes_received;
+extern uint64_t oom_stats_n_bytes_removed_dns;
+extern uint64_t oom_stats_n_bytes_removed_cell;
+extern uint64_t oom_stats_n_bytes_removed_geoip;
+extern uint64_t oom_stats_n_bytes_removed_hsdir;
+
void dump_cell_pool_usage(int severity);
size_t packed_cell_mem_cost(void);