]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Memory reporting.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 20 Jul 2007 15:51:06 +0000 (15:51 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 20 Jul 2007 15:51:06 +0000 (15:51 +0000)
git-svn-id: file:///svn/unbound/trunk@447 be551aaa-1e26-0410-a405-d3ace91eadb9

17 files changed:
daemon/worker.c
doc/Changelog
services/listen_dnsport.c
services/listen_dnsport.h
services/mesh.c
services/mesh.h
services/outside_network.c
services/outside_network.h
testcode/fake_event.c
util/alloc.c
util/alloc.h
util/netevent.c
util/netevent.h
util/region-allocator.c
util/region-allocator.h
util/storage/slabhash.c
util/storage/slabhash.h

index 32ad955bf8908991a9b60ee41044292daa652b57..4043c4ff8c8b7a4ee7573a7d0d4038e558f41ef4 100644 (file)
@@ -54,6 +54,7 @@
 #include "services/outside_network.h"
 #include "services/outbound_list.h"
 #include "services/cache/rrset.h"
+#include "services/cache/infra.h"
 #include "services/mesh.h"
 #include "util/data/msgparse.h"
 #include "util/data/msgencode.h"
 /** Size of an UDP datagram */
 #define NORMAL_UDP_SIZE        512 /* bytes */
 
+/** Report on memory usage by this thread and global */
+static void
+worker_mem_report(struct worker* worker)
+{
+       size_t total, front, back, mesh, msg, rrset, infra, ac, superac;
+       size_t me;
+       if(verbosity < VERB_ALGO) 
+               return;
+       front = listen_get_mem(worker->front);
+       back = outnet_get_mem(worker->back);
+       msg = slabhash_get_mem(worker->env.msg_cache);
+       rrset = slabhash_get_mem(&worker->env.rrset_cache->table);
+       infra = slabhash_get_mem(worker->env.infra_cache->hosts);
+       mesh = mesh_get_mem(worker->env.mesh);
+       ac = alloc_get_mem(&worker->alloc);
+       superac = alloc_get_mem(&worker->daemon->superalloc);
+       me = sizeof(*worker) + sizeof(*worker->base) + sizeof(*worker->comsig)
+               + comm_point_get_mem(worker->cmd_com) + 
+               sizeof(worker->rndstate) + region_get_mem(worker->scratchpad);
+       total = front+back+mesh+msg+rrset+infra+ac+superac+me;
+       log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
+               "rrset=%u infra=%u alloccache=%u globalalloccache=%u me=%u",
+               (unsigned)total, (unsigned)front, (unsigned)back, 
+               (unsigned)mesh, (unsigned)msg, (unsigned)rrset, 
+               (unsigned)infra, (unsigned)ac, (unsigned)superac, 
+               (unsigned)me);
+}
+
 void 
 worker_send_cmd(struct worker* worker, ldns_buffer* buffer,
        enum worker_commands cmd)
@@ -95,6 +124,7 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
 
        if(error != 0) {
                mesh_report_reply(worker->env.mesh, &e, 0, reply_info);
+               worker_mem_report(worker);
                return 0;
        }
        /* sanity check. */
@@ -105,9 +135,11 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
                /* error becomes timeout for the module as if this reply
                 * never arrived. */
                mesh_report_reply(worker->env.mesh, &e, 0, reply_info);
+               worker_mem_report(worker);
                return 0;
        }
        mesh_report_reply(worker->env.mesh, &e, 1, reply_info);
+       worker_mem_report(worker);
        return 0;
 }
 
@@ -122,6 +154,7 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
        verbose(VERB_ALGO, "worker scvd callback for qstate %p", e->qstate);
        if(error != 0) {
                mesh_report_reply(worker->env.mesh, e, 0, reply_info);
+               worker_mem_report(worker);
                return 0;
        }
        /* sanity check. */
@@ -133,9 +166,11 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
                 * never arrived. */
                verbose(VERB_ALGO, "worker: bad reply handled as timeout");
                mesh_report_reply(worker->env.mesh, e, 0, reply_info);
+               worker_mem_report(worker);
                return 0;
        }
        mesh_report_reply(worker->env.mesh, e, 1, reply_info);
+       worker_mem_report(worker);
        return 0;
 }
 
@@ -507,6 +542,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
                /* the max request number has been reached, stop accepting */
                listen_pushback(worker->front);
        }
+       worker_mem_report(worker);
        return 0;
 }
 
@@ -680,6 +716,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
                worker_delete(worker);
                return 0;
        }
+       worker_mem_report(worker);
        return 1;
 }
 
@@ -696,6 +733,7 @@ worker_delete(struct worker* worker)
                return;
        mesh_stats(worker->env.mesh, "mesh has");
        server_stats_log(&worker->stats, worker->thread_num);
+       worker_mem_report(worker);
        mesh_delete(worker->env.mesh);
        listen_delete(worker->front);
        outside_network_delete(worker->back);
index b89ac23ed2b402cdcfb7b9dcbf39881e166857cd..500c6e73b34c74594adf9b583aab21037f4f789b 100644 (file)
@@ -10,6 +10,8 @@
        - TODO items from forgery-resilience draft.
          and on memory handling improvements.
        - renamed module_event_timeout to module_event_noreply.
+       - memory reporting code; reports on memory usage after handling
+         a network packet (not on cache replies).
 
 19 July 2007: Wouter
        - shuffle NS selection when getting nameserver target addresses.
index c996e16d3e89b3eaa14f9669091a3e543c3d990e..125685d15dee72f0856b5db79dfcb7d40ff233c4 100644 (file)
@@ -452,3 +452,16 @@ void listening_ports_free(struct listen_port* list)
                list = nx;
        }
 }
+
+size_t listen_get_mem(struct listen_dnsport* listen)
+{
+       size_t s = sizeof(*listen) + sizeof(*listen->base) + 
+               sizeof(*listen->udp_buff) + 
+               ldns_buffer_capacity(listen->udp_buff);
+       struct listen_list* p;
+       for(p = listen->cps; p; p = p->next) {
+               s += sizeof(*p);
+               s += comm_point_get_mem(p->com);
+       }
+       return s;
+}
index b8e0f16e4404e6c6f36f7c7909f346b4a34d8a4f..4fabea50b63be2e58e8e67c4f5e0b83cc9a857d7 100644 (file)
@@ -141,9 +141,17 @@ void listen_resume(struct listen_dnsport* listen);
 
 /**
  * delete the listening structure
+ * @param listen: listening structure.
  */
 void listen_delete(struct listen_dnsport* listen);
 
+/**
+ * get memory size used by the listening structs
+ * @param listen: listening structure.
+ * @return: size in bytes.
+ */
+size_t listen_get_mem(struct listen_dnsport* listen);
+
 /**
  * Create and bind nonblocking UDP socket
  * @param addr: address info ready to make socket.
index 27c1e51250bcdf99dee3b66ad390a1672dfde7a7..0061c1e1da66a57b9d3fa49edd2947d910c5ce11 100644 (file)
@@ -575,3 +575,16 @@ mesh_stats(struct mesh_area* mesh, const char* str)
                timehist_log(mesh->histogram);
        }
 }
+
+size_t 
+mesh_get_mem(struct mesh_area* mesh)
+{
+       struct mesh_state* m;
+       size_t s = sizeof(*mesh) + sizeof(struct timehist) +
+               sizeof(struct th_buck)*mesh->histogram->num;
+       RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
+               /* all, including m itself allocated in qstate region */
+               s += region_get_mem(m->s.region);
+       }
+       return s;
+}
index bf6a863e09c52ec5098b006df55762ada01f6e50..75afdcb702bb48a712bf3a9a149407624b5e8f55 100644 (file)
@@ -350,4 +350,11 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
  */
 void mesh_stats(struct mesh_area* mesh, const char* str);
 
+/**
+ * Calculate memory size in use by mesh and all queries inside it.
+ * @param mesh: the mesh to examine.
+ * @return size in bytes.
+ */
+size_t mesh_get_mem(struct mesh_area* mesh);
+
 #endif /* SERVICES_MESH_H */
index facc87cd72c58d2899007b15bdf1905915ec43b0..da0aec649184d6451ce1a41e6b45492eff22ab1c 100644 (file)
@@ -1200,3 +1200,51 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
                serviced_delete(sq); 
        }
 }
+
+/** get memory used by waiting tcp entry (in use or not) */
+static size_t
+waiting_tcp_get_mem(struct waiting_tcp* w)
+{
+       size_t s;
+       if(!w) return 0;
+       s = sizeof(*w) + w->pkt_len;
+       if(w->timer)
+               s += comm_timer_get_mem(w->timer);
+       return s;
+}
+
+size_t outnet_get_mem(struct outside_network* outnet)
+{
+       size_t i;
+       struct waiting_tcp* w;
+       struct serviced_query* sq;
+       struct service_callback* sb;
+       size_t s = sizeof(*outnet) + sizeof(*outnet->base) + 
+               sizeof(*outnet->udp_buff) + 
+               ldns_buffer_capacity(outnet->udp_buff);
+       /* second buffer is not ours */
+       s += sizeof(struct comm_point*)*outnet->num_udp4;
+       for(i=0; i<outnet->num_udp4; i++)
+               s += comm_point_get_mem(outnet->udp4_ports[i]);
+       s += sizeof(struct comm_point*)*outnet->num_udp6;
+       for(i=0; i<outnet->num_udp6; i++)
+               s += comm_point_get_mem(outnet->udp6_ports[i]);
+       s += sizeof(struct pending_tcp*)*outnet->num_tcp;
+       for(i=0; i<outnet->num_tcp; i++) {
+               s += sizeof(struct pending_tcp);
+               s += comm_point_get_mem(outnet->tcp_conns[i]->c);
+               if(outnet->tcp_conns[i]->query)
+                       s += waiting_tcp_get_mem(outnet->tcp_conns[i]->query);
+       }
+       for(w=outnet->tcp_wait_first; w; w = w->next_waiting)
+               s += waiting_tcp_get_mem(w);
+       s += sizeof(*outnet->pending);
+       s += sizeof(struct pending) * outnet->pending->count;
+       s += sizeof(*outnet->serviced);
+       RBTREE_FOR(sq, struct serviced_query*, outnet->serviced) {
+               s += sizeof(*sq) + sq->qbuflen;
+               for(sb = sq->cblist; sb; sb = sb->next)
+                       s += sizeof(*sb);
+       }
+       return s;
+}
index 0e7e59c33fdd32ddfd7cad23c7db72e40833f558..8765c93e8631035e024349e17a34b7b0e54f82e6 100644 (file)
@@ -363,4 +363,12 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
  */
 void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg);
 
+/**
+ * Get memory size in use by outside network.
+ * Counts buffers and outstanding query (serviced queries) malloced data.
+ * @param outnet: outside network structure.
+ * @return size in bytes.
+ */
+size_t outnet_get_mem(struct outside_network* outnet);
+
 #endif /* OUTSIDE_NETWORK_H */
index 88e6b94d8036d37dd912b921d05c37080e4b1ead..83c477edf93d4f625269ab6e7317b2bcc7cdd8db 100644 (file)
@@ -901,4 +901,19 @@ void comm_point_delete(struct comm_point* c)
        free(c);
 }
 
+size_t listen_get_mem(struct listen_dnsport* ATTR_UNUSED(listen))
+{
+       return 0;
+}
+
+size_t outnet_get_mem(struct outside_network* ATTR_UNUSED(outnet))
+{
+       return 0;
+}
+
+size_t comm_point_get_mem(struct comm_point* ATTR_UNUSED(c))
+{
+       return 0;
+}
+
 /*********** End of Dummy routines ***********/
index cdebd3c5255a25716f22cd7ebd878c64526e6e6a..a652706fbb29ccd0517b71d4db75aad8d8f39ba0 100644 (file)
@@ -234,3 +234,16 @@ alloc_stats(struct alloc_cache* alloc)
        log_info("%salloc: %d in cache.", alloc->super?"":"sup",
                (int)alloc->num_quar);
 }
+
+size_t alloc_get_mem(struct alloc_cache* alloc)
+{
+       size_t s = sizeof(*alloc);
+       if(!alloc->super) { 
+               lock_quick_lock(&alloc->lock); /* superalloc needs locking */
+       }
+       s += sizeof(alloc_special_t) * alloc->num_quar;
+       if(!alloc->super) {
+               lock_quick_unlock(&alloc->lock);
+       }
+       return s;
+}
index 9a0115608611584841adc6845f3b333ab2ccf8ee..761213e8bcf7197ead2e6830014effa2f4288b66 100644 (file)
@@ -119,6 +119,13 @@ alloc_special_t* alloc_special_obtain(struct alloc_cache* alloc);
  */
 void alloc_special_release(struct alloc_cache* alloc, alloc_special_t* mem);
 
+/**
+ * Get memory size of alloc cache, alloc structure including special types.
+ * @param alloc: on what alloc.
+ * @return size in bytes.
+ */
+size_t alloc_get_mem(struct alloc_cache* alloc);
+
 /**
  * Print debug information (statistics).
  * @param alloc: on what alloc.
index 41adeaadd43f1969c7d34e6ea12f1d09159279fd..363a501444f31e6992ea3ad32885b9b0887ed0dc 100644 (file)
@@ -984,6 +984,24 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
        }
 }
 
+size_t comm_point_get_mem(struct comm_point* c)
+{
+       size_t s;
+       if(!c) 
+               return 0;
+       s = sizeof(*c) + sizeof(*c->ev);
+       if(c->timeout) 
+               s += sizeof(*c->timeout);
+       if(c->type == comm_tcp || c->type == comm_local)
+               s += sizeof(*c->buffer) + ldns_buffer_capacity(c->buffer);
+       if(c->type == comm_tcp_accept) {
+               int i;
+               for(i=0; i<c->max_tcp_count; i++)
+                       s += comm_point_get_mem(c->tcp_handlers[i]);
+       }
+       return s;
+}
+
 struct comm_timer* 
 comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg)
 {
@@ -1055,6 +1073,12 @@ comm_timer_is_set(struct comm_timer* timer)
        return (int)timer->ev_timer->enabled;
 }
 
+size_t 
+comm_timer_get_mem(struct comm_timer* timer)
+{
+       return sizeof(*timer) + sizeof(struct internal_timer);
+}
+
 struct comm_signal* 
 comm_signal_create(struct comm_base* base,
         void (*callback)(int, void*), void* cb_arg)
index 460bc01341b9706bab6a8021f8dc939c6e4e1b33..a1bb56bbb76ed5ef3c8effd70f31a87f935019c7 100644 (file)
@@ -384,6 +384,15 @@ void comm_point_stop_listening(struct comm_point* c);
  */
 void comm_point_start_listening(struct comm_point* c, int newfd, int sec);
 
+/**
+ * Get size of memory used by comm point.
+ * For TCP handlers this includes subhandlers.
+ * For UDP handlers, this does not include the (shared) UDP buffer.
+ * @param c: commpoint.
+ * @return size in bytes.
+ */
+size_t comm_point_get_mem(struct comm_point* c);
+
 /**
  * create timer. Not active upon creation.
  * @param base: event handling base.
@@ -420,6 +429,13 @@ void comm_timer_delete(struct comm_timer* timer);
  */
 int comm_timer_is_set(struct comm_timer* timer);
 
+/**
+ * Get size of memory used by comm timer.
+ * @param timer: the timer to examine.
+ * @return size in bytes.
+ */
+size_t comm_timer_get_mem(struct comm_timer* timer);
+
 /**
  * Create a signal handler. Call signal_bind() later to bind to a signal.
  * @param base: communication base to use.
index daa1c0a89decc67ce9d810cfc598d34bf4d5fad3..b3946edf48ffc79cf2991f543b27a6220fb4b0be 100644 (file)
@@ -508,3 +508,14 @@ region_log_stats(region_type *region)
        }
        log_info("memory: %s", buf);
 }
+
+size_t 
+region_get_mem(region_type* region)
+{
+       size_t s = sizeof(*region);
+       s += region->total_allocated + region->chunk_size - region->allocated;
+       s += region->maximum_cleanup_count * sizeof(cleanup_type);
+       if(region->recycle_bin)
+               s += sizeof(struct recycle_elem*)*region->large_object_size;
+       return s;
+}
index 3c857cb0cfb2c3c833cd1b860b539dcf08fb1006..c10897d9c04f6382ac999e75788295e83fab8518 100644 (file)
@@ -173,4 +173,7 @@ size_t region_get_recycle_size(region_type* region);
 /** Debug print REGION statistics to LOG */
 void region_log_stats(region_type *region);
 
+/** get total memory size in use by region */
+size_t region_get_mem(region_type* region);
+
 #endif /* _REGION_ALLOCATOR_H_ */
index 61393c1e191aef086bc712982ae63c2a3ab150a4..2ce58f7cc8dcbb3b9d0cab53ddc356df04c82f08 100644 (file)
@@ -144,6 +144,18 @@ size_t slabhash_get_size(struct slabhash* sl)
        return total;
 }
 
+size_t slabhash_get_mem(struct slabhash* sl)
+{      
+       size_t i, total = sizeof(*sl);
+       for(i=0; i<sl->size; i++) {
+               lock_quick_lock(&sl->array[i]->lock);
+               total += sizeof(struct lruhash) + sl->array[i]->space_used +
+                       sizeof(struct lruhash_bin)*sl->array[i]->size;
+               lock_quick_unlock(&sl->array[i]->lock);
+       }
+       return total;
+}
+
 struct lruhash* slabhash_gettable(struct slabhash* sl, hashvalue_t hash)
 {
        return sl->array[slab_idx(sl, hash)];
index d530d7a1e50fa50001a9d90f9a2cc790dba25b2b..be7fd07d43d9d8ddbb1823e4680b864bb792fb5a 100644 (file)
@@ -142,9 +142,17 @@ void slabhash_status(struct slabhash* table, const char* id, int extended);
 /**
  * Retrieve slab hash total size.
  * @param table: hash table.
+ * @return size configured as max.
  */
 size_t slabhash_get_size(struct slabhash* table);
 
+/**
+ * Retrieve slab hash current memory use.
+ * @param table: hash table.
+ * @return memory in use.
+ */
+size_t slabhash_get_mem(struct slabhash* table);
+
 /**
  * Get lruhash table for a given hash value
  * @param table: slabbed hash table.