Fix gprof bottlenecks on exit nodes found by Jacob.
Apparently all the stuff that does a linear scan over all the DNS cache entries can get really expensive when your DNS cache is very large. It's hard to say how much this will help performance, since gprof doesn't count time spent in OpenSSL or zlib, but I'd guess 10%. Also, this patch removes calls to assert_connection_ok() from inside the read and write callbacks, which are similarly unneeded, and a little costlier than I'm happy with. This is probably worth backporting to 0.2.0.
This commit is contained in:
parent
c4c7dcd453
commit
b262e76563
|
@ -1,4 +1,12 @@
|
|||
Changes in version 0.2.1.16-?? - 2009-??-??
|
||||
o Major performance improvements (on 0.2.0.x):
|
||||
- Disable and refactor some debugging checks that forced a linear scan
|
||||
over the whole server-side DNS cache. These accounted for over 50%
|
||||
of CPU time on a relatively busy exit node's gprof profile. Found by
|
||||
Jacob.
|
||||
- Disable some debugging checks that appeared in exit node profile
|
||||
data.
|
||||
|
||||
o Minor bugfixes (on 0.2.0.x):
|
||||
- Log correct error messages for DNS-related network errors on
|
||||
Windows.
|
||||
|
|
18
src/or/dns.c
18
src/or/dns.c
|
@ -736,15 +736,25 @@ void
|
|||
assert_connection_edge_not_dns_pending(edge_connection_t *conn)
|
||||
{
|
||||
pending_connection_t *pend;
|
||||
cached_resolve_t **resolve;
|
||||
cached_resolve_t search;
|
||||
|
||||
#if 1
|
||||
cached_resolve_t *resolve;
|
||||
strlcpy(search.address, conn->_base.address, sizeof(search.address));
|
||||
resolve = HT_FIND(cache_map, &cache_root, &search);
|
||||
if (!resolve)
|
||||
return;
|
||||
for (pend = resolve->pending_connections; pend; pend = pend->next) {
|
||||
tor_assert(pend->conn != conn);
|
||||
}
|
||||
#else
|
||||
cached_resolve_t **resolve;
|
||||
HT_FOREACH(resolve, cache_map, &cache_root) {
|
||||
for (pend = (*resolve)->pending_connections;
|
||||
pend;
|
||||
pend = pend->next) {
|
||||
for (pend = (*resolve)->pending_connections; pend; pend = pend->next) {
|
||||
tor_assert(pend->conn != conn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Log an error and abort if any connection waiting for a DNS resolve is
|
||||
|
|
|
@ -451,7 +451,7 @@ conn_read_callback(int fd, short event, void *_conn)
|
|||
|
||||
log_debug(LD_NET,"socket %d wants to read.",conn->s);
|
||||
|
||||
assert_connection_ok(conn, time(NULL));
|
||||
/* assert_connection_ok(conn, time(NULL)); */
|
||||
|
||||
if (connection_handle_read(conn) < 0) {
|
||||
if (!conn->marked_for_close) {
|
||||
|
@ -483,7 +483,7 @@ conn_write_callback(int fd, short events, void *_conn)
|
|||
|
||||
LOG_FN_CONN(conn, (LOG_DEBUG, LD_NET, "socket %d wants to write.",conn->s));
|
||||
|
||||
assert_connection_ok(conn, time(NULL));
|
||||
/* assert_connection_ok(conn, time(NULL)); */
|
||||
|
||||
if (connection_handle_write(conn, 0) < 0) {
|
||||
if (!conn->marked_for_close) {
|
||||
|
@ -529,7 +529,7 @@ conn_close_if_marked(int i)
|
|||
return 0; /* nothing to see here, move along */
|
||||
now = time(NULL);
|
||||
assert_connection_ok(conn, now);
|
||||
assert_all_pending_dns_resolves_ok();
|
||||
/* assert_all_pending_dns_resolves_ok(); */
|
||||
|
||||
log_debug(LD_NET,"Cleaning up connection (fd %d).",conn->s);
|
||||
if ((conn->s >= 0 || conn->linked_conn) && connection_wants_to_flush(conn)) {
|
||||
|
|
Loading…
Reference in New Issue