]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
lib/slab: introduce sl_allocz() function and use it in Babel
authorToke Høiland-Jørgensen <toke@toke.dk>
Tue, 24 Nov 2020 01:32:13 +0000 (02:32 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 24 Nov 2020 01:36:31 +0000 (02:36 +0100)
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().

lib/resource.h
lib/slab.c
proto/babel/babel.c
proto/babel/packets.c

index ad17d9ed45be5da41017935639124ae988c838bd..b56bcff557faf03c80508c86dbb544f4ff3058cf 100644 (file)
@@ -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 *);
 
 /*
index c3035b45b222a3e17ad9d2acd8b1ed66c1a9d3a4..f31355e02b567c5cba636bf5e36ca4e2c2c55d67 100644 (file)
@@ -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)
 {
@@ -278,6 +286,22 @@ no_partial:
   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
  * @s: slab
index 618abaa8ab605ef76666f6dcfadb453c203b303e..4b6b9d7f9f6f4c49e990ab21337fed99d5da5052 100644 (file)
@@ -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;
index d4ecf649dedc02a5ba39432ee32c72b9c10d26b6..415ac3f9c50006376b67dc13439f2c47443afe8b 100644 (file)
@@ -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)
     {