Blame SOURCES/rhbz1073640.8.patch

f43afa
From 66283521fac33ac5716b71a6d2662093aec409c1 Mon Sep 17 00:00:00 2001
f43afa
From: David Smith <dsmith@redhat.com>
f43afa
Date: Wed, 12 Mar 2014 09:07:58 -0500
f43afa
Subject: [PATCH] Improve task_finder/utrace shutdown.
f43afa
f43afa
* runtime/stp_utrace.c (utrace_exit): Move the call to
f43afa
  stp_task_work_exit() up above the calls to free the kmem caches. This
f43afa
  make sure any running task work items don't have the memory freed out
f43afa
  from under them.
f43afa
* runtime/linux/task_finder2.c (__stp_task_finder_cleanup): Move
f43afa
  utrace_shutdown() call into stap_stop_task_finder().
f43afa
  (stap_stop_task_finder): Call utrace_shutdown() directly. Wait to make
f43afa
  sure all tracepoint probes are finished.
f43afa
---
f43afa
 runtime/linux/task_finder2.c | 24 +++++++-----------------
f43afa
 runtime/stp_utrace.c         | 27 +++++++++++++++++++--------
f43afa
 2 files changed, 26 insertions(+), 25 deletions(-)
f43afa
f43afa
diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
f43afa
index a3abc16..ef074c5 100644
f43afa
--- a/runtime/linux/task_finder2.c
f43afa
+++ b/runtime/linux/task_finder2.c
f43afa
@@ -418,15 +418,6 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops)
f43afa
 	debug_task_finder_report();
f43afa
 }
f43afa
 
f43afa
-static void
f43afa
-__stp_task_finder_cleanup(void)
f43afa
-{
f43afa
-	// The utrace_shutdown() function detaches and deletes
f43afa
-	// everything for us - we don't have to go through each
f43afa
-	// engine.
f43afa
-	utrace_shutdown();
f43afa
-}
f43afa
-
f43afa
 static char *
f43afa
 __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
f43afa
 {
f43afa
@@ -1849,16 +1840,16 @@ stap_stop_task_finder(void)
f43afa
 	atomic_set(&__stp_task_finder_state, __STP_TF_STOPPING);
f43afa
 
f43afa
 	debug_task_finder_report();
f43afa
-#if 0
f43afa
-	/* We don't need this since __stp_task_finder_cleanup()
f43afa
-	 * removes everything by calling utrace_shutdown(). */
f43afa
-	stap_utrace_detach_ops(&__stp_utrace_task_finder_ops);
f43afa
-#endif
f43afa
-	__stp_task_finder_cleanup();
f43afa
+
f43afa
+	// The utrace_shutdown() function detaches and cleans up
f43afa
+	// everything for us - we don't have to go through each
f43afa
+	// engine. This also means that the attach_count could end up
f43afa
+	// > 0 (since we don't got through each engine individually).
f43afa
+	utrace_shutdown();
f43afa
+
f43afa
 	debug_task_finder_report();
f43afa
 	atomic_set(&__stp_task_finder_state, __STP_TF_STOPPED);
f43afa
 
f43afa
-#if 0
f43afa
 	/* Now that all the engines are detached, make sure
f43afa
 	 * all the callbacks are finished.  If they aren't, we'll
f43afa
 	 * crash the kernel when the module is removed. */
f43afa
@@ -1873,7 +1864,6 @@ stap_stop_task_finder(void)
f43afa
 		printk(KERN_ERR "it took %d polling loops to quit.\n", i);
f43afa
 #endif
f43afa
 	debug_task_finder_report();
f43afa
-#endif
f43afa
 
f43afa
 	/* Make sure all outstanding task work requests are canceled. */
f43afa
 	__stp_tf_cancel_task_work();
f43afa
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c
f43afa
index 89ea0e4..a6f363d 100644
f43afa
--- a/runtime/stp_utrace.c
f43afa
+++ b/runtime/stp_utrace.c
f43afa
@@ -286,12 +286,18 @@ static int utrace_exit(void)
f43afa
 {
f43afa
 	utrace_shutdown();
f43afa
 
f43afa
-	if (utrace_cachep)
f43afa
-		kmem_cache_destroy(utrace_cachep);
f43afa
-	if (utrace_engine_cachep)
f43afa
-		kmem_cache_destroy(utrace_engine_cachep);
f43afa
-
f43afa
 	stp_task_work_exit();
f43afa
+
f43afa
+	/* After utrace_shutdown() and stp_task_work_exit() (and the
f43afa
+	 * code in stap_stop_task_finder()), we're *sure* there are no
f43afa
+	 * tracepoint probes or task work items running or scheduled
f43afa
+	 * to be run. So, now would be a great time to actually free
f43afa
+	 * everything. */
f43afa
+
f43afa
+	if (utrace_cachep)
f43afa
+		kmem_cache_destroy(utrace_cachep);
f43afa
+	if (utrace_engine_cachep)
f43afa
+		kmem_cache_destroy(utrace_engine_cachep);
f43afa
 	return 0;
f43afa
 }
f43afa
 
f43afa
@@ -373,9 +379,14 @@ static void utrace_shutdown(void)
f43afa
 	unregister_trace_sys_exit(utrace_report_syscall_exit, NULL);
f43afa
 	tracepoint_synchronize_unregister();
f43afa
 
f43afa
-	/* After calling tracepoint_synchronize_unregister(), we're
f43afa
-	 * sure there are no outstanding tracepoint probes being
f43afa
-	 * called.  So, now would be a great time to free everything. */
f43afa
+	/* After tracepoint_synchronize_unregister(), we're *sure*
f43afa
+	 * there will be no new tracepoint probes running. There could
f43afa
+	 * be currently running tracepoint probes or task work
f43afa
+	 * items. So, now would be a great time to cleanup.
f43afa
+	 *
f43afa
+	 * Currently running items should be OK, since
f43afa
+	 * utrace_cleanup() just puts the memory back into the utrace
f43afa
+	 * kmem caches. */
f43afa
 	
f43afa
 #ifdef STP_TF_DEBUG
f43afa
 	printk(KERN_ERR "%s:%d - freeing task-specific\n", __FUNCTION__, __LINE__);
f43afa
-- 
f43afa
1.8.3.1
f43afa