aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToke Høiland-Jørgensen <toke@toke.dk>2020-11-24 02:32:13 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2020-11-24 02:36:31 +0100
commitdb2d29073acfd4086fca18ba43a5ed6baccaa8ad (patch)
tree59901d070b0c1c1ba6a1e42fc4957898c15820d6
parent3347aaafec5b269637604d1ea5f5969797beadea (diff)
downloadbird-db2d29073acfd4086fca18ba43a5ed6baccaa8ad.tar.gz
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: baac7009063d ("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().
-rw-r--r--lib/resource.h1
-rw-r--r--lib/slab.c24
-rw-r--r--proto/babel/babel.c7
-rw-r--r--proto/babel/packets.c8
4 files changed, 32 insertions, 8 deletions
diff --git a/lib/resource.h b/lib/resource.h
index ad17d9ed..b56bcff5 100644
--- a/lib/resource.h
+++ b/lib/resource.h
@@ -83,6 +83,7 @@ typedef struct slab slab;
slab *sl_new(pool *, unsigned size);
void *sl_alloc(slab *);
+void *sl_allocz(slab *);
void sl_free(slab *, void *);
/*
diff --git a/lib/slab.c b/lib/slab.c
index c3035b45..f31355e0 100644
--- a/lib/slab.c
+++ b/lib/slab.c
@@ -88,6 +88,14 @@ sl_alloc(slab *s)
return o->data;
}
+void *
+sl_allocz(slab *s)
+{
+ void *obj = sl_alloc(s);
+ memset(obj, 0, s->size);
+ return obj;
+}
+
void
sl_free(slab *s, void *oo)
{
@@ -279,6 +287,22 @@ no_partial:
}
/**
+ * 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
* @s: slab
* @oo: object returned by sl_alloc()
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 618abaa8..4b6b9d7f 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -113,7 +113,7 @@ babel_get_source(struct babel_proto *p, struct babel_entry *e, u64 router_id)
if (s)
return s;
- s = sl_alloc(p->source_slab);
+ s = sl_allocz(p->source_slab);
s->router_id = router_id;
s->expires = current_time() + BABEL_GARBAGE_INTERVAL;
s->seqno = 0;
@@ -159,8 +159,7 @@ babel_get_route(struct babel_proto *p, struct babel_entry *e, struct babel_neigh
if (r)
return r;
- r = sl_alloc(p->route_slab);
- memset(r, 0, sizeof(*r));
+ r = sl_allocz(p->route_slab);
r->e = e;
r->neigh = nbr;
@@ -323,7 +322,7 @@ babel_add_seqno_request(struct babel_proto *p, struct babel_entry *e,
}
/* No entries found */
- sr = sl_alloc(p->seqno_slab);
+ sr = sl_allocz(p->seqno_slab);
found:
sr->router_id = router_id;
diff --git a/proto/babel/packets.c b/proto/babel/packets.c
index d4ecf649..415ac3f9 100644
--- a/proto/babel/packets.c
+++ b/proto/babel/packets.c
@@ -1144,7 +1144,6 @@ babel_read_tlv(struct babel_tlv *hdr,
return PARSE_ERROR;
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);
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);
list queue;
- msgn->msg = *msg;
+ *msgn = (struct babel_msg_node) { .msg = *msg };
init_list(&queue);
add_tail(&queue, NODE msgn);
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_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);
babel_kick_queue(ifa);
}
@@ -1386,7 +1386,7 @@ babel_process_packet(struct babel_pkt_header *pkt, int len,
break;
}
- msg = sl_alloc(p->msg_slab);
+ msg = sl_allocz(p->msg_slab);
res = babel_read_tlv(tlv, &msg->msg, &state);
if (res == PARSE_SUCCESS)
{