]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Fix gprof bottlenecks on exit nodes found by Jacob.
authorNick Mathewson <nickm@torproject.org>
Wed, 3 Jun 2009 17:52:03 +0000 (13:52 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 3 Jun 2009 17:52:03 +0000 (13:52 -0400)
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.

ChangeLog
src/or/dns.c
src/or/main.c

index 2ae76b730cd8959a011322b171e1a885cfef11db..b2ba413511dd2ec44aec92c5b8842868bd801cd4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
index ad5b5de4050d98baf896035b95b442360af34599..74852b0f70bb169fc02d3b5d9d2fd47467a7dae9 100644 (file)
@@ -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
index a26fd0eff880fdf5862c8ff45c81fa65a39a77eb..8fc712bba39745565af17c2d61c9de423dded547 100644 (file)
@@ -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)) {