]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
fixup: slab.c: Prevent running sl_free after slab_free
authorKaterina Kubecova <katerina.kubecova@nic.cz>
Thu, 13 Mar 2025 09:57:34 +0000 (10:57 +0100)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Thu, 13 Mar 2025 09:57:34 +0000 (10:57 +0100)
lib/slab.c

index cf2abc699d22c86c60e719f724d53a105b0ba792..2ab8a6d48f834e57e20126a48a4db8b36799a121 100644 (file)
@@ -793,28 +793,27 @@ slab_free(resource *r)
   /* At this point, only one thread manipulating the slab is expected */
   slab *s = (slab *) r;
 
+  struct sl_head *new_partials = sl_cleanup_full_heads(s);
+  ASSERT_DIE(new_partials == &slh_dummy_last_partial);
+  sl_cleanup_partial_heads(s, new_partials);
+
+  ev_postpone(&s->event_clean);
+
   /* No more thread ends are relevant, we are ending anyway */
   bird_thread_end_unregister(&s->thread_end);
 
-  /* Free partial heads */
-  struct sl_head *h = atomic_load_explicit(&s->partial_heads, memory_order_relaxed);
-  while (SL_GET_STATE(h) != slh_dummy)
-  {
-    struct sl_head *nh = atomic_load_explicit(&h->next, memory_order_relaxed);
-    sl_free_page(h);
-    h = nh;
-  }
-  atomic_store_explicit(&s->partial_heads, &slh_dummy_last_partial, memory_order_relaxed);
+  /* Assert there are no partial heads */
+  ASSERT_DIE(atomic_load_explicit(&s->partial_heads, memory_order_relaxed) == &slh_dummy_last_partial);
 
-  /* Free full heads */
-  h = atomic_load_explicit(&s->full_heads, memory_order_relaxed);
-  while (SL_GET_STATE(h) != slh_dummy)
+  /* Assert there is only the skipped full head */
+  struct sl_head *h = atomic_load_explicit(&s->full_heads, memory_order_relaxed);
+  if (h !=  &slh_dummy_last_full)
   {
-    struct sl_head *nh = atomic_load_explicit(&h->next, memory_order_relaxed);
+    ASSERT_DIE(atomic_load_explicit(&h->next, memory_order_relaxed) == &slh_dummy_last_full);
+    ASSERT_DIE(atomic_load_explicit(&h->num_full, memory_order_relaxed) == 0);
     sl_free_page(h);
-    h = nh;
+    atomic_store_explicit(&s->full_heads, &slh_dummy_last_full, memory_order_relaxed);
   }
-  atomic_store_explicit(&s->full_heads, &slh_dummy_last_full, memory_order_relaxed);
 
   /* Free thread heads */
   for (long unsigned int i = 0; i < page_size / (sizeof(struct sl_head *_Atomic)); i++)