lib/slab: introduce sl_allocz() function and use it in Babel
The babel protocol code was initialising objects returned from the slab
allocator by assigning to each of the struct members individually, but
wasn't touching the NODE member while doing so. This leads to warnings on
debug builds since commit:
baac700906
("List expensive check.")
To fix this, introduce an sl_allocz() variant of the slab allocator which
will zero out the memory before returning it, and switch all the babel call
sites to use this version. The overhead for doing this should be negligible
for small objects, and in the case of babel, the largest object being
allocated was being zeroed anyway, so we can drop the memset in
babel_read_tlv().
This commit is contained in:
parent
3347aaafec
commit
db2d29073a
4 changed files with 32 additions and 8 deletions
|
@ -83,6 +83,7 @@ typedef struct slab slab;
|
||||||
|
|
||||||
slab *sl_new(pool *, unsigned size);
|
slab *sl_new(pool *, unsigned size);
|
||||||
void *sl_alloc(slab *);
|
void *sl_alloc(slab *);
|
||||||
|
void *sl_allocz(slab *);
|
||||||
void sl_free(slab *, void *);
|
void sl_free(slab *, void *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
24
lib/slab.c
24
lib/slab.c
|
@ -88,6 +88,14 @@ sl_alloc(slab *s)
|
||||||
return o->data;
|
return o->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
sl_allocz(slab *s)
|
||||||
|
{
|
||||||
|
void *obj = sl_alloc(s);
|
||||||
|
memset(obj, 0, s->size);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sl_free(slab *s, void *oo)
|
sl_free(slab *s, void *oo)
|
||||||
{
|
{
|
||||||
|
@ -278,6 +286,22 @@ no_partial:
|
||||||
goto okay;
|
goto okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sl_allocz - allocate an object from Slab and zero it
|
||||||
|
* @s: slab
|
||||||
|
*
|
||||||
|
* sl_allocz() allocates space for a single object from the
|
||||||
|
* Slab and returns a pointer to the object after zeroing out
|
||||||
|
* the object memory.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
sl_allocz(slab *s)
|
||||||
|
{
|
||||||
|
void *obj = sl_alloc(s);
|
||||||
|
memset(obj, 0, s->data_size);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sl_free - return a free object back to a Slab
|
* sl_free - return a free object back to a Slab
|
||||||
* @s: slab
|
* @s: slab
|
||||||
|
|
|
@ -113,7 +113,7 @@ babel_get_source(struct babel_proto *p, struct babel_entry *e, u64 router_id)
|
||||||
if (s)
|
if (s)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
s = sl_alloc(p->source_slab);
|
s = sl_allocz(p->source_slab);
|
||||||
s->router_id = router_id;
|
s->router_id = router_id;
|
||||||
s->expires = current_time() + BABEL_GARBAGE_INTERVAL;
|
s->expires = current_time() + BABEL_GARBAGE_INTERVAL;
|
||||||
s->seqno = 0;
|
s->seqno = 0;
|
||||||
|
@ -159,8 +159,7 @@ babel_get_route(struct babel_proto *p, struct babel_entry *e, struct babel_neigh
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sl_alloc(p->route_slab);
|
r = sl_allocz(p->route_slab);
|
||||||
memset(r, 0, sizeof(*r));
|
|
||||||
|
|
||||||
r->e = e;
|
r->e = e;
|
||||||
r->neigh = nbr;
|
r->neigh = nbr;
|
||||||
|
@ -323,7 +322,7 @@ babel_add_seqno_request(struct babel_proto *p, struct babel_entry *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No entries found */
|
/* No entries found */
|
||||||
sr = sl_alloc(p->seqno_slab);
|
sr = sl_allocz(p->seqno_slab);
|
||||||
|
|
||||||
found:
|
found:
|
||||||
sr->router_id = router_id;
|
sr->router_id = router_id;
|
||||||
|
|
|
@ -1144,7 +1144,6 @@ babel_read_tlv(struct babel_tlv *hdr,
|
||||||
return PARSE_ERROR;
|
return PARSE_ERROR;
|
||||||
|
|
||||||
state->current_tlv_endpos = tlv_data[hdr->type].min_length;
|
state->current_tlv_endpos = tlv_data[hdr->type].min_length;
|
||||||
memset(msg, 0, sizeof(*msg));
|
|
||||||
|
|
||||||
int res = tlv_data[hdr->type].read_tlv(hdr, msg, state);
|
int res = tlv_data[hdr->type].read_tlv(hdr, msg, state);
|
||||||
if (res != PARSE_SUCCESS)
|
if (res != PARSE_SUCCESS)
|
||||||
|
@ -1278,7 +1277,7 @@ babel_send_unicast(union babel_msg *msg, struct babel_iface *ifa, ip_addr dest)
|
||||||
struct babel_msg_node *msgn = sl_alloc(p->msg_slab);
|
struct babel_msg_node *msgn = sl_alloc(p->msg_slab);
|
||||||
list queue;
|
list queue;
|
||||||
|
|
||||||
msgn->msg = *msg;
|
*msgn = (struct babel_msg_node) { .msg = *msg };
|
||||||
init_list(&queue);
|
init_list(&queue);
|
||||||
add_tail(&queue, NODE msgn);
|
add_tail(&queue, NODE msgn);
|
||||||
babel_write_queue(ifa, &queue);
|
babel_write_queue(ifa, &queue);
|
||||||
|
@ -1305,7 +1304,8 @@ babel_enqueue(union babel_msg *msg, struct babel_iface *ifa)
|
||||||
{
|
{
|
||||||
struct babel_proto *p = ifa->proto;
|
struct babel_proto *p = ifa->proto;
|
||||||
struct babel_msg_node *msgn = sl_alloc(p->msg_slab);
|
struct babel_msg_node *msgn = sl_alloc(p->msg_slab);
|
||||||
msgn->msg = *msg;
|
|
||||||
|
*msgn = (struct babel_msg_node) { .msg = *msg };
|
||||||
add_tail(&ifa->msg_queue, NODE msgn);
|
add_tail(&ifa->msg_queue, NODE msgn);
|
||||||
babel_kick_queue(ifa);
|
babel_kick_queue(ifa);
|
||||||
}
|
}
|
||||||
|
@ -1386,7 +1386,7 @@ babel_process_packet(struct babel_pkt_header *pkt, int len,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = sl_alloc(p->msg_slab);
|
msg = sl_allocz(p->msg_slab);
|
||||||
res = babel_read_tlv(tlv, &msg->msg, &state);
|
res = babel_read_tlv(tlv, &msg->msg, &state);
|
||||||
if (res == PARSE_SUCCESS)
|
if (res == PARSE_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue