commit 59e114832e7f67cb2fac1258c7423b6359160505 Merge: d31bcc4 d603384 Author: Nick Mathewson nickm@torproject.org Date: Sun Aug 24 13:09:08 2014 -0400
Merge branch 'bug11792_1_squashed'
Conflicts: src/or/circuitlist.c
changes/bug11792 | 15 ++++++ src/common/torgzip.c | 65 +++++++++++++++++++++- src/common/torgzip.h | 3 ++ src/or/circuitlist.c | 145 ++++++++++++++++++++++++++++++++++++++++++-------- src/or/relay.c | 1 + 5 files changed, 206 insertions(+), 23 deletions(-)
diff --cc src/or/circuitlist.c index d6bc674,6853420..e04b4b9 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@@ -1975,7 -2009,11 +2034,9 @@@ conns_compare_by_buffer_age_(const voi void circuits_handle_oom(size_t current_allocation) { - /* Let's hope there's enough slack space for this allocation here... */ - smartlist_t *circlist = smartlist_new(); + smartlist_t *circlist; + smartlist_t *connection_array = get_connection_array(); + int conn_idx; - circuit_t *circ; size_t mem_to_recover; size_t mem_recovered=0; int n_circuits_killed=0; @@@ -2015,17 -2056,46 +2077,54 @@@ /* This is O(n log n); there are faster algorithms we could use instead. * Let's hope this doesn't happen enough to be in the critical path. */ smartlist_sort(circlist, circuits_compare_by_oldest_queued_item_); + + /* Fix up the indices before we run into trouble */ + SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) { + circ->global_circuitlist_idx = circ_sl_idx; + } SMARTLIST_FOREACH_END(circ); + - /* Okay, now the worst circuits are at the front of the list. Let's mark - * them, and reclaim their storage aggressively. */ ++ ++ /* Now sort the connection array ... */ + now_ms_for_buf_cmp = now_ms; + smartlist_sort(connection_array, conns_compare_by_buffer_age_); + now_ms_for_buf_cmp = 0; + + /* Fix up the connection array to its new order. */ + SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) { + conn->conn_array_index = conn_sl_idx; + } SMARTLIST_FOREACH_END(conn); + + /* Okay, now the worst circuits and connections are at the front of their + * respective lists. Let's mark them, and reclaim their storage + * aggressively. */ + conn_idx = 0; SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) { - size_t n = n_cells_in_circ_queues(circ); + size_t n; size_t freed; + + /* Free storage in any non-linked directory connections that have buffered + * data older than this circuit. */ + while (conn_idx < smartlist_len(connection_array)) { + connection_t *conn = smartlist_get(connection_array, conn_idx); + uint32_t conn_age = conn_get_buffer_age(conn, now_ms); + if (conn_age < circ->age_tmp) { + break; + } + if (conn->type == CONN_TYPE_DIR && conn->linked_conn == NULL) { + if (!conn->marked_for_close) + connection_mark_for_close(conn); + mem_recovered += single_conn_free_bytes(conn); + + ++n_dirconns_killed; + + if (mem_recovered >= mem_to_recover) + goto done_recovering_mem; + } + ++conn_idx; + } + + /* Now, kill the circuit. */ + n = n_cells_in_circ_queues(circ); if (! circ->marked_for_close) { circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); } @@@ -2048,10 -2120,14 +2149,12 @@@ chunks. */
log_notice(LD_GENERAL, "Removed "U64_FORMAT" bytes by killing %d circuits; " - "%d circuits remain alive.", + "%d circuits remain alive. Also killed %d non-linked directory " + "connections.", U64_PRINTF_ARG(mem_recovered), n_circuits_killed, - smartlist_len(circlist) - n_circuits_killed); + smartlist_len(circlist) - n_circuits_killed, + n_dirconns_killed); - - smartlist_free(circlist); }
/** Verify that cpath layer <b>cp</b> has all of its invariants
tor-commits@lists.torproject.org