diff options
author | hunt <hunt> | 2007-11-01 19:19:33 +0000 |
---|---|---|
committer | hunt <hunt> | 2007-11-01 19:19:33 +0000 |
commit | 68e81635a3fd6d11f6e605995c72801c66305171 (patch) | |
tree | 3871759d4412aedebf85975ccfcedfe712613559 | |
parent | d47936fc8f3245d9f14797eb7bf2e876b3c37c99 (diff) | |
download | systemtap-steved-68e81635a3fd6d11f6e605995c72801c66305171.tar.gz systemtap-steved-68e81635a3fd6d11f6e605995c72801c66305171.tar.xz systemtap-steved-68e81635a3fd6d11f6e605995c72801c66305171.zip |
2007-11-01 Martin Hunt <hunt@redhat.com>
* procfs.c, control.c, transport.c: Recognize when stapio
is detached and disable delayed work. Enable when attached.
Cleanup code to destroy workqueue on exit.
-rw-r--r-- | runtime/transport/ChangeLog | 6 | ||||
-rw-r--r-- | runtime/transport/control.c | 17 | ||||
-rw-r--r-- | runtime/transport/procfs.c | 14 | ||||
-rw-r--r-- | runtime/transport/transport.c | 49 | ||||
-rw-r--r-- | runtime/transport/transport.h | 1 |
5 files changed, 54 insertions, 33 deletions
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index 66811376..4872fa11 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,9 @@ +2007-11-01 Martin Hunt <hunt@redhat.com> + + * procfs.c, control.c, transport.c: Recognize when stapio + is detached and disable delayed work. Enable when attached. + Cleanup code to destroy workqueue on exit. + 2007-10-12 Martin Hunt <hunt@redhat.com> * transport.c (_stp_ask_for_symbols): Don't ask for diff --git a/runtime/transport/control.c b/runtime/transport/control.c index ae731659..7846572a 100644 --- a/runtime/transport/control.c +++ b/runtime/transport/control.c @@ -261,6 +261,8 @@ static int _stp_ctl_send (int type, void *data, int len) } else { while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--) msleep (5); + if (err > 0) + wake_up_interruptible(&_stp_ctl_wq); } kbug("returning %d\n", err); return err; @@ -368,26 +370,19 @@ static int _stp_sym_close_cmd (struct inode *inode, struct file *file) return 0; } -static int _stp_ctl_opens = 0; static int _stp_ctl_open_cmd (struct inode *inode, struct file *file) { - /* only allow one reader */ - if (_stp_ctl_opens) + if (_stp_attached) return -1; - _stp_ctl_opens++; - _stp_pid = current->pid; - utt_overwrite_flag = 0; + _stp_attach(); return 0; } static int _stp_ctl_close_cmd (struct inode *inode, struct file *file) { - if (_stp_ctl_opens) - _stp_ctl_opens--; - _stp_pid = 0; - if (!_stp_exit_flag) - utt_overwrite_flag = 1; + if (_stp_attached) + _stp_detach(); return 0; } diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c index 88740847..069e379e 100644 --- a/runtime/transport/procfs.c +++ b/runtime/transport/procfs.c @@ -324,6 +324,8 @@ static int _stp_ctl_send (int type, void *data, int len) } else { while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--) msleep (5); + if (err > 0) + wake_up_interruptible(&_stp_ctl_wq); } return err; } @@ -430,23 +432,19 @@ static int _stp_sym_close_cmd (struct inode *inode, struct file *file) return 0; } -static int _stp_ctl_opens = 0; static int _stp_ctl_open_cmd (struct inode *inode, struct file *file) { - /* only allow one reader */ - if (_stp_ctl_opens) + if (_stp_attached) return -1; - _stp_ctl_opens++; - _stp_pid = current->pid; + _stp_attach(); return 0; } static int _stp_ctl_close_cmd (struct inode *inode, struct file *file) { - if (_stp_ctl_opens) - _stp_ctl_opens--; - _stp_pid = 0; + if (_stp_attached) + _stp_detach(); return 0; } diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index d44d6851..0a959917 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -47,7 +47,8 @@ void probe_exit(void); int probe_start(void); void _stp_exit(void); void _stp_handle_start (struct _stp_msg_start *st); - +static void _stp_detach(void); +static void _stp_attach(void); /* check for new workqueue API */ #ifdef DECLARE_DELAYED_WORK @@ -115,6 +116,7 @@ static void _stp_cleanup_and_exit (int dont_rmmod) if (!_stp_exit_called) { int failures; + _stp_exit_flag = 1; unregister_module_notifier(&_stp_module_load_nb); /* we only want to do this stuff once */ @@ -142,6 +144,34 @@ static void _stp_cleanup_and_exit (int dont_rmmod) } /* + * Called when stapio closes the control channel. + */ +static void _stp_detach(void) +{ + kbug("detach\n"); + _stp_attached = 0; + _stp_pid = 0; + + if (!_stp_exit_flag) + utt_overwrite_flag = 1; + + cancel_delayed_work(&_stp_work); + wake_up_interruptible(&_stp_ctl_wq); +} + +/* + * Called when stapio opens the control channel. + */ +static void _stp_attach(void) +{ + kbug("attach\n"); + _stp_attached = 1; + _stp_pid = current->pid; + utt_overwrite_flag = 0; + queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER); +} + +/* * _stp_work_queue - periodically check for IO or exit * This is run by a kernel thread and may sleep. */ @@ -162,12 +192,9 @@ static void _stp_work_queue (void *data) wake_up_interruptible(&_stp_ctl_wq); /* if exit flag is set AND we have finished with probe_start() */ - if (unlikely(_stp_exit_flag && _stp_start_finished)) { + if (unlikely(_stp_exit_flag && _stp_start_finished)) _stp_cleanup_and_exit(0); - cancel_delayed_work(&_stp_work); - flush_workqueue(_stp_wq); - wake_up_interruptible(&_stp_ctl_wq); - } else + else if (likely(_stp_attached)) queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER); } @@ -179,18 +206,14 @@ static void _stp_work_queue (void *data) */ void _stp_transport_close() { - kbug("************** transport_close *************\n"); + kbug("%d: ************** transport_close *************\n", current->pid); _stp_cleanup_and_exit(1); - cancel_delayed_work(&_stp_work); destroy_workqueue(_stp_wq); - wake_up_interruptible(&_stp_ctl_wq); - unregister_module_notifier(&_stp_module_load_nb); _stp_unregister_ctl_channel(); if (_stp_utt) utt_trace_remove(_stp_utt); _stp_free_modules(); _stp_kill_time(); _stp_print_cleanup(); /* free print buffers */ - kbug("---- CLOSED ----\n"); } @@ -257,9 +280,7 @@ int _stp_transport_init(void) _stp_wq = create_workqueue("systemtap"); if (!_stp_wq) goto err3; - - queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER); - + /* request symbolic information */ _stp_ask_for_symbols(); return 0; diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h index 0a83001e..6dc00d2b 100644 --- a/runtime/transport/transport.h +++ b/runtime/transport/transport.h @@ -26,4 +26,5 @@ int _stp_pid = 0; uid_t _stp_uid = 0; gid_t _stp_gid = 0; pid_t _stp_init_pid = 0; +int _stp_attached = 0; #endif /* _TRANSPORT_TRANSPORT_H_ */ |