]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: Limit depth of unused thread list
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 23 Aug 2018 00:59:46 +0000 (20:59 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 23 Aug 2018 13:23:46 +0000 (09:23 -0400)
The master->unused list was unbounded during normal operation.
A full BGP feed on my machine left 11k threads on the unused
list, taking up over 2mb of data.  This seemed a bit excessive,
reduce to a limit of 10.

Also fix a crash that this exposed where we assumed that a thread
structure was not deleted.

Future committers can make this configurable? or modify
the value to something better for their system.  I am
dubious of the value of this.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/thread.c

index c6894be4ee51c1d10a1fee7203f12a60ea85142e..52bc79ffe6ba528ad81afb4df505baed8d394c04 100644 (file)
@@ -532,17 +532,23 @@ static struct thread *thread_trim_head(struct thread_list *list)
        return NULL;
 }
 
+#define THREAD_UNUSED_DEPTH 10
+
 /* Move thread to unuse list. */
 static void thread_add_unuse(struct thread_master *m, struct thread *thread)
 {
        assert(m != NULL && thread != NULL);
        assert(thread->next == NULL);
        assert(thread->prev == NULL);
-       thread->ref = NULL;
 
-       thread->type = THREAD_UNUSED;
        thread->hist->total_active--;
-       thread_list_add(&m->unuse, thread);
+       memset(thread, 0, sizeof(struct thread));
+       thread->type = THREAD_UNUSED;
+
+       if (m->unuse.count < THREAD_UNUSED_DEPTH)
+               thread_list_add(&m->unuse, thread);
+       else
+               XFREE(MTYPE_THREAD, thread);
 }
 
 /* Free all unused thread. */
@@ -1175,17 +1181,19 @@ void thread_cancel_event(struct thread_master *master, void *arg)
  */
 void thread_cancel(struct thread *thread)
 {
-       assert(thread->master->owner == pthread_self());
+       struct thread_master *master = thread->master;
 
-       pthread_mutex_lock(&thread->master->mtx);
+       assert(master->owner == pthread_self());
+
+       pthread_mutex_lock(&master->mtx);
        {
                struct cancel_req *cr =
                        XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
                cr->thread = thread;
-               listnode_add(thread->master->cancel_req, cr);
-               do_thread_cancel(thread->master);
+               listnode_add(master->cancel_req, cr);
+               do_thread_cancel(master);
        }
-       pthread_mutex_unlock(&thread->master->mtx);
+       pthread_mutex_unlock(&master->mtx);
 }
 
 /**