Memory reporting.

git-svn-id: file:///svn/unbound/trunk@447 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-07-20 15:51:06 +00:00
parent 522220494a
commit 1460965467
17 changed files with 246 additions and 0 deletions

View 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"
@ -68,6 +69,34 @@
/** 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);

View 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.

View 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;
}

View 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.

View 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;
}

View 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 */

View 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;
}

View 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 */

View 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 ***********/

View 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;
}

View 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.

View 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)

View 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.

View 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;
}

View 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_ */

View 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)];

View 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.