summaryrefslogtreecommitdiffstats
path: root/runtime/transport/control.c
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-03-12 17:12:38 -0700
committerJosh Stone <jistone@redhat.com>2009-03-13 14:32:31 -0700
commit52aeb26b8d83c26e00adaf70bbf5a3a828689fb2 (patch)
treefcc966c5906c8edf79ba0e2500d9a475d2396cf1 /runtime/transport/control.c
parent2497c78e8aa704366683dad56fc8d749a5e92f52 (diff)
downloadsystemtap-steved-52aeb26b8d83c26e00adaf70bbf5a3a828689fb2.tar.gz
systemtap-steved-52aeb26b8d83c26e00adaf70bbf5a3a828689fb2.tar.xz
systemtap-steved-52aeb26b8d83c26e00adaf70bbf5a3a828689fb2.zip
PR9947: move runtime cleanup out of the work queue
The kernel lockdep checking found a possible deadlock if a forced rmmod tried to destroy _stp_work_queue at the same time that the work queue was unregistering tracepoints. An unlikely scenario, but still possible. Now the work queue will just issue a STP_REQUEST_EXIT down to usermode, and usermode will echo back an STP_EXIT that triggers the actual probe cleanup. This way the unregistrations are happening in exactly the same context as the registrations were.
Diffstat (limited to 'runtime/transport/control.c')
-rw-r--r--runtime/transport/control.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index edde244d..680d7306 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -13,6 +13,8 @@ static _stp_mempool_t *_stp_pool_q;
static struct list_head _stp_ctl_ready_q;
static DEFINE_SPINLOCK(_stp_ctl_ready_lock);
+static void _stp_cleanup_and_exit(int send_exit);
+
static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
u32 type;
@@ -46,7 +48,7 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz
}
break;
case STP_EXIT:
- _stp_exit_flag = 1;
+ _stp_cleanup_and_exit(1);
break;
case STP_BULK:
#ifdef STP_BULKMODE
@@ -93,6 +95,9 @@ static void _stp_ctl_write_dbug(int type, void *data, int len)
case STP_TRANSPORT:
_dbug("sending STP_TRANSPORT\n");
break;
+ case STP_REQUEST_EXIT:
+ _dbug("sending STP_REQUEST_EXIT\n");
+ break;
default:
_dbug("ERROR: unknown message type: %d\n", type);
break;