mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 06:33:44 +01:00
Prop#329 OOM: Handle freeing conflux queues on OOM
We use the oldest-circ-first method here, since that seems good for conflux: queues could briefly spike, but the bad case is if they are maliciously bloated to stick around for a long time. The tradeoff here is that it is possible to kill old circuits on a relay quickly, but that has always been the case with this algorithm choice. Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
e0881a669a
commit
b999051e44
@ -2739,6 +2739,7 @@ circuits_handle_oom(size_t current_allocation)
|
|||||||
mem_recovered += n * packed_cell_mem_cost();
|
mem_recovered += n * packed_cell_mem_cost();
|
||||||
mem_recovered += half_stream_alloc;
|
mem_recovered += half_stream_alloc;
|
||||||
mem_recovered += freed;
|
mem_recovered += freed;
|
||||||
|
mem_recovered += conflux_get_circ_bytes_allocation(circ);
|
||||||
|
|
||||||
if (mem_recovered >= mem_to_recover)
|
if (mem_recovered >= mem_to_recover)
|
||||||
goto done_recovering_mem;
|
goto done_recovering_mem;
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
static inline uint64_t cwnd_sendable(const circuit_t *on_circ,
|
static inline uint64_t cwnd_sendable(const circuit_t *on_circ,
|
||||||
uint64_t in_usec, uint64_t our_usec);
|
uint64_t in_usec, uint64_t our_usec);
|
||||||
|
|
||||||
|
/* Track the total number of bytes used by all ooo_q so it can be used by the
|
||||||
|
* OOM handler to assess. */
|
||||||
|
static uint64_t total_ooo_q_bytes = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if we should multiplex a specific relay command or not.
|
* Determine if we should multiplex a specific relay command or not.
|
||||||
*
|
*
|
||||||
@ -156,6 +160,41 @@ conflux_get_max_seq_recv(const conflux_t *cfx)
|
|||||||
return max_seq_recv;
|
return max_seq_recv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the total memory allocation the circuit is using by conflux. If this
|
||||||
|
* circuit is not a Conflux circuit, 0 is returned. */
|
||||||
|
uint64_t
|
||||||
|
conflux_get_circ_bytes_allocation(const circuit_t *circ)
|
||||||
|
{
|
||||||
|
if (circ->conflux) {
|
||||||
|
return smartlist_len(circ->conflux->ooo_q) * sizeof(conflux_cell_t);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the total memory allocation in bytes by the subsystem.
|
||||||
|
*
|
||||||
|
* At the moment, only out of order queues are consiered. */
|
||||||
|
uint64_t
|
||||||
|
conflux_get_total_bytes_allocation(void)
|
||||||
|
{
|
||||||
|
return total_ooo_q_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The OOM handler is asking us to try to free at least bytes_to_remove. */
|
||||||
|
size_t
|
||||||
|
conflux_handle_oom(size_t bytes_to_remove)
|
||||||
|
{
|
||||||
|
(void) bytes_to_remove;
|
||||||
|
|
||||||
|
/* We are not doing anything on the sets, the OOM handler will trigger a
|
||||||
|
* circuit clean up which will affect conflux sets, by pruning oldest
|
||||||
|
* circuits. */
|
||||||
|
|
||||||
|
log_info(LD_CIRC, "OOM handler triggered. OOO queus allocation: %" PRIu64,
|
||||||
|
total_ooo_q_bytes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a circuit has package window space to send, and is
|
* Returns true if a circuit has package window space to send, and is
|
||||||
* not blocked locally.
|
* not blocked locally.
|
||||||
|
@ -2879,6 +2879,8 @@ cell_queues_check_size(void)
|
|||||||
alloc += geoip_client_cache_total;
|
alloc += geoip_client_cache_total;
|
||||||
const size_t dns_cache_total = dns_cache_total_allocation();
|
const size_t dns_cache_total = dns_cache_total_allocation();
|
||||||
alloc += dns_cache_total;
|
alloc += dns_cache_total;
|
||||||
|
const size_t conflux_total = conflux_get_total_bytes_allocation();
|
||||||
|
alloc += conflux_total;
|
||||||
if (alloc >= get_options()->MaxMemInQueues_low_threshold) {
|
if (alloc >= get_options()->MaxMemInQueues_low_threshold) {
|
||||||
last_time_under_memory_pressure = approx_time();
|
last_time_under_memory_pressure = approx_time();
|
||||||
if (alloc >= get_options()->MaxMemInQueues) {
|
if (alloc >= get_options()->MaxMemInQueues) {
|
||||||
@ -2910,6 +2912,14 @@ cell_queues_check_size(void)
|
|||||||
oom_stats_n_bytes_removed_dns += removed;
|
oom_stats_n_bytes_removed_dns += removed;
|
||||||
alloc -= removed;
|
alloc -= removed;
|
||||||
}
|
}
|
||||||
|
/* Like onion service above, try to go down to 10% if we are above 20% */
|
||||||
|
if (conflux_total > get_options()->MaxMemInQueues / 5) {
|
||||||
|
const size_t bytes_to_remove =
|
||||||
|
conflux_total - (size_t)(get_options()->MaxMemInQueues / 10);
|
||||||
|
removed = conflux_handle_oom(bytes_to_remove);
|
||||||
|
oom_stats_n_bytes_removed_cell += removed;
|
||||||
|
alloc -= removed;
|
||||||
|
}
|
||||||
removed = circuits_handle_oom(alloc);
|
removed = circuits_handle_oom(alloc);
|
||||||
oom_stats_n_bytes_removed_cell += removed;
|
oom_stats_n_bytes_removed_cell += removed;
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user