Blob Blame History Raw
From 66283521fac33ac5716b71a6d2662093aec409c1 Mon Sep 17 00:00:00 2001
From: David Smith <dsmith@redhat.com>
Date: Wed, 12 Mar 2014 09:07:58 -0500
Subject: [PATCH] Improve task_finder/utrace shutdown.

* runtime/stp_utrace.c (utrace_exit): Move the call to
  stp_task_work_exit() up above the calls to free the kmem caches. This
  make sure any running task work items don't have the memory freed out
  from under them.
* runtime/linux/task_finder2.c (__stp_task_finder_cleanup): Move
  utrace_shutdown() call into stap_stop_task_finder().
  (stap_stop_task_finder): Call utrace_shutdown() directly. Wait to make
  sure all tracepoint probes are finished.
---
 runtime/linux/task_finder2.c | 24 +++++++-----------------
 runtime/stp_utrace.c         | 27 +++++++++++++++++++--------
 2 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
index a3abc16..ef074c5 100644
--- a/runtime/linux/task_finder2.c
+++ b/runtime/linux/task_finder2.c
@@ -418,15 +418,6 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops)
 	debug_task_finder_report();
 }
 
-static void
-__stp_task_finder_cleanup(void)
-{
-	// The utrace_shutdown() function detaches and deletes
-	// everything for us - we don't have to go through each
-	// engine.
-	utrace_shutdown();
-}
-
 static char *
 __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
 {
@@ -1849,16 +1840,16 @@ stap_stop_task_finder(void)
 	atomic_set(&__stp_task_finder_state, __STP_TF_STOPPING);
 
 	debug_task_finder_report();
-#if 0
-	/* We don't need this since __stp_task_finder_cleanup()
-	 * removes everything by calling utrace_shutdown(). */
-	stap_utrace_detach_ops(&__stp_utrace_task_finder_ops);
-#endif
-	__stp_task_finder_cleanup();
+
+	// The utrace_shutdown() function detaches and cleans up
+	// everything for us - we don't have to go through each
+	// engine. This also means that the attach_count could end up
+	// > 0 (since we don't got through each engine individually).
+	utrace_shutdown();
+
 	debug_task_finder_report();
 	atomic_set(&__stp_task_finder_state, __STP_TF_STOPPED);
 
-#if 0
 	/* Now that all the engines are detached, make sure
 	 * all the callbacks are finished.  If they aren't, we'll
 	 * crash the kernel when the module is removed. */
@@ -1873,7 +1864,6 @@ stap_stop_task_finder(void)
 		printk(KERN_ERR "it took %d polling loops to quit.\n", i);
 #endif
 	debug_task_finder_report();
-#endif
 
 	/* Make sure all outstanding task work requests are canceled. */
 	__stp_tf_cancel_task_work();
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c
index 89ea0e4..a6f363d 100644
--- a/runtime/stp_utrace.c
+++ b/runtime/stp_utrace.c
@@ -286,12 +286,18 @@ static int utrace_exit(void)
 {
 	utrace_shutdown();
 
-	if (utrace_cachep)
-		kmem_cache_destroy(utrace_cachep);
-	if (utrace_engine_cachep)
-		kmem_cache_destroy(utrace_engine_cachep);
-
 	stp_task_work_exit();
+
+	/* After utrace_shutdown() and stp_task_work_exit() (and the
+	 * code in stap_stop_task_finder()), we're *sure* there are no
+	 * tracepoint probes or task work items running or scheduled
+	 * to be run. So, now would be a great time to actually free
+	 * everything. */
+
+	if (utrace_cachep)
+		kmem_cache_destroy(utrace_cachep);
+	if (utrace_engine_cachep)
+		kmem_cache_destroy(utrace_engine_cachep);
 	return 0;
 }
 
@@ -373,9 +379,14 @@ static void utrace_shutdown(void)
 	unregister_trace_sys_exit(utrace_report_syscall_exit, NULL);
 	tracepoint_synchronize_unregister();
 
-	/* After calling tracepoint_synchronize_unregister(), we're
-	 * sure there are no outstanding tracepoint probes being
-	 * called.  So, now would be a great time to free everything. */
+	/* After tracepoint_synchronize_unregister(), we're *sure*
+	 * there will be no new tracepoint probes running. There could
+	 * be currently running tracepoint probes or task work
+	 * items. So, now would be a great time to cleanup.
+	 *
+	 * Currently running items should be OK, since
+	 * utrace_cleanup() just puts the memory back into the utrace
+	 * kmem caches. */
 	
 #ifdef STP_TF_DEBUG
 	printk(KERN_ERR "%s:%d - freeing task-specific\n", __FUNCTION__, __LINE__);
-- 
1.8.3.1