mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 14:47:09 +00:00
Memory reporting.
git-svn-id: file:///svn/unbound/trunk@447 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
522220494a
commit
1460965467
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 ***********/
|
||||
|
13
util/alloc.c
13
util/alloc.c
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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)];
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user