summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhunt <hunt>2005-11-30 08:38:13 +0000
committerhunt <hunt>2005-11-30 08:38:13 +0000
commit1296e5e2c706c3ff7858bd2903dcd76c3547d31b (patch)
tree25c56fb79edd476aa003757d63511520546653a2
parent4cc73b3da4778a8189ddbf798403ee59dbbe6ae6 (diff)
downloadsystemtap-steved-1296e5e2c706c3ff7858bd2903dcd76c3547d31b.tar.gz
systemtap-steved-1296e5e2c706c3ff7858bd2903dcd76c3547d31b.tar.xz
systemtap-steved-1296e5e2c706c3ff7858bd2903dcd76c3547d31b.zip
2005-11-30 Martin Hunt <hunt@redhat.com>
* transport.h (STP_WORK_TIMER): Declare. * transport.c (_stp_work_queue): Wake up every STP_WORK_QUEUE jiffies and check IO and exit status. (_stp_handle_exit): Deleted. * procfs.c (_stp_proc_write_cmd): Just set exit flag on STP_EXIT. (_stp_write): Don't call wake_up_interruptible.
-rw-r--r--runtime/transport/ChangeLog9
-rw-r--r--runtime/transport/procfs.c11
-rw-r--r--runtime/transport/transport.c32
-rw-r--r--runtime/transport/transport.h3
4 files changed, 39 insertions, 16 deletions
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 62baa416..4353fb93 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,12 @@
+2005-11-30 Martin Hunt <hunt@redhat.com>
+
+ * transport.h (STP_WORK_TIMER): Declare.
+ * transport.c (_stp_work_queue): Wake up every STP_WORK_QUEUE
+ jiffies and check IO and exit status.
+ (_stp_handle_exit): Deleted.
+ * procfs.c (_stp_proc_write_cmd): Just set exit flag on STP_EXIT.
+ (_stp_write): Don't call wake_up_interruptible.
+
2005-10-17 Martin Hunt <hunt@redhat.com>
* transport.c (_stp_handle_start): Grab semaphore before
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index 7bba3033..7db6e658 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -93,10 +93,7 @@ static ssize_t _stp_proc_write_cmd (struct file *file, const char __user *buf,
break;
}
case STP_EXIT:
- /* Cannot call _stp_handle_exit() directly here */
- /* because the buffers may be full and stpd won't be able */
- /* to empty them until this handler returns. */
- schedule_work (&stp_exit);
+ _stp_exit_flag = 1;
break;
case STP_TRANSPORT_INFO:
{
@@ -160,15 +157,11 @@ static int _stp_write (int type, void *data, int len)
memcpy (bptr->buf, data, len);
bptr->len = len;
-
/* put it on the pool of ready buffers */
spin_lock(&_stp_ready_lock);
list_add_tail(&bptr->list, &_stp_ready_q);
spin_unlock(&_stp_ready_lock);
- /* now wake up readers */
- wake_up_interruptible(&_stp_proc_wq);
-
return len;
}
@@ -236,7 +229,7 @@ static int _stp_set_buffers(int num)
int i;
struct list_head *p;
- printk("stp_set_buffers %d\n", num);
+ //printk("stp_set_buffers %d\n", num);
if (num == 0 || num == _stp_current_buffers)
return _stp_current_buffers;
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 36d5fc5a..c6c4b1b4 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -29,14 +29,15 @@ MODULE_PARM_DESC(_stp_pid, "daemon pid");
int _stp_target = 0;
int _stp_exit_called = 0;
+int _stp_exit_flag = 0;
/* forward declarations */
void probe_exit(void);
int probe_start(void);
void _stp_exit(void);
void _stp_handle_start (struct transport_start *st);
-static void _stp_handle_exit (void *data);
-static DECLARE_WORK(stp_exit, _stp_handle_exit, NULL);
+static void _stp_work_queue (void *data);
+static DECLARE_WORK(stp_exit, _stp_work_queue, NULL);
int _stp_transport_open(struct transport_info *info);
#include "procfs.c"
@@ -142,13 +143,29 @@ static void _stp_cleanup_and_exit (int closing)
}
/*
- * _stp_handle_exit - handle STP_EXIT
+ * _stp_work_queue - periodically check for IO or exit
*/
-static void _stp_handle_exit (void *data)
+static void _stp_work_queue (void *data)
{
- down (&_stp_start_mutex);
- _stp_cleanup_and_exit(0);
- up (&_stp_start_mutex);
+ int do_io = 0;
+
+ spin_lock(&_stp_ready_lock);
+ if (!list_empty(&_stp_ready_q))
+ do_io = 1;
+ spin_unlock(&_stp_ready_lock);
+
+ if (do_io)
+ wake_up_interruptible(&_stp_proc_wq);
+
+ if (_stp_exit_flag) {
+ cancel_delayed_work(&stp_exit);
+ down (&_stp_start_mutex);
+ _stp_cleanup_and_exit(0);
+ up (&_stp_start_mutex);
+ wake_up_interruptible(&_stp_proc_wq);
+ } else
+ schedule_delayed_work(&stp_exit, STP_WORK_TIMER);
+
}
/**
@@ -232,6 +249,7 @@ int _stp_transport_init(void)
kbug("transport_init from %ld %ld\n", (long)_stp_pid, (long)current->pid);
_stp_register_procfs();
+ schedule_delayed_work(&stp_exit, STP_WORK_TIMER);
return 0;
}
diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h
index e5e087a2..e62260ab 100644
--- a/runtime/transport/transport.h
+++ b/runtime/transport/transport.h
@@ -12,6 +12,9 @@ void _stp_warn (const char *fmt, ...);
#define STP_BUFFER_SIZE 8192
+/* how often the work queue wakes up and checks buffers */
+#define STP_WORK_TIMER (HZ/100)
+
#ifdef STP_RELAYFS
static unsigned n_subbufs = 16;
static unsigned subbuf_size = 65536;