aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2008-09-17 14:29:31 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2008-09-17 14:29:31 -0400
commitaeb7a10b15401c80fc1c5ecf93b1e22240f046e6 (patch)
tree011952ec7f286dbea2316322394994c8ff1d5452
parent364619e98672692ad1f58d96ffab531a304868e5 (diff)
ftdev: don't forget to disable events
Otherwise required buffers may not be present anymore. This patch also fixes some minor initialization issues.
-rw-r--r--include/litmus/ftdev.h8
-rw-r--r--litmus/ftdev.c72
-rw-r--r--litmus/trace.c2
3 files changed, 57 insertions, 25 deletions
diff --git a/include/litmus/ftdev.h b/include/litmus/ftdev.h
index ac937fb733..8df916d1fc 100644
--- a/include/litmus/ftdev.h
+++ b/include/litmus/ftdev.h
@@ -16,11 +16,14 @@ struct ftdev;
16typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no); 16typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no);
17typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no); 17typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no);
18 18
19struct ftdev_event;
20
19struct ftdev_minor { 21struct ftdev_minor {
20 struct ft_buffer* buf; 22 struct ft_buffer* buf;
21 unsigned int readers; 23 unsigned int readers;
22 struct mutex lock; 24 struct mutex lock;
23 unsigned active_events; 25 /* FIXME: filter for authorized events */
26 struct ftdev_event* events;
24}; 27};
25 28
26struct ftdev { 29struct ftdev {
@@ -28,7 +31,6 @@ struct ftdev {
28 /* FIXME: don't waste memory, allocate dynamically */ 31 /* FIXME: don't waste memory, allocate dynamically */
29 struct ftdev_minor minor[MAX_FTDEV_MINORS]; 32 struct ftdev_minor minor[MAX_FTDEV_MINORS];
30 unsigned int minor_cnt; 33 unsigned int minor_cnt;
31 /* FIXME: track enabled/disabled events */
32 ftdev_alloc_t alloc; 34 ftdev_alloc_t alloc;
33 ftdev_free_t free; 35 ftdev_free_t free;
34}; 36};
@@ -36,7 +38,7 @@ struct ftdev {
36struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size); 38struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size);
37void free_ft_buffer(struct ft_buffer* buf); 39void free_ft_buffer(struct ft_buffer* buf);
38 40
39void ftdev_init(struct ftdev* ftdev); 41void ftdev_init(struct ftdev* ftdev, struct module* owner);
40int register_ftdev(struct ftdev* ftdev, const char* name, int major); 42int register_ftdev(struct ftdev* ftdev, const char* name, int major);
41 43
42#endif 44#endif
diff --git a/litmus/ftdev.c b/litmus/ftdev.c
index 8e7d8e9dfe..fe3005db6d 100644
--- a/litmus/ftdev.c
+++ b/litmus/ftdev.c
@@ -58,6 +58,41 @@ void free_ft_buffer(struct ft_buffer* buf)
58 } 58 }
59} 59}
60 60
61struct ftdev_event {
62 int id;
63 struct ftdev_event* next;
64};
65
66static int activate(struct ftdev_event** chain, int id)
67{
68 struct ftdev_event* ev = kmalloc(sizeof(struct ftdev_event), GFP_KERNEL);
69 if (ev) {
70 printk(KERN_INFO
71 "Enabling feather-trace event %d.\n", (int) id);
72 ft_enable_event(id);
73 ev->id = id;
74 ev->next = *chain;
75 *chain = ev;
76 }
77 return ev ? 0 : -ENOMEM;
78}
79
80static void deactivate(struct ftdev_event** chain, int id)
81{
82 struct ftdev_event **last = chain;
83 struct ftdev_event *pos = *chain;
84 while (pos) {
85 if (pos->id == id) {
86 *last = pos->next;
87 kfree(pos);
88 printk(KERN_INFO
89 "Disabling feather-trace event %d.\n", (int) id);
90 ft_disable_event(id);
91 break;
92 }
93 }
94}
95
61static int ftdev_open(struct inode *in, struct file *filp) 96static int ftdev_open(struct inode *in, struct file *filp)
62{ 97{
63 struct ftdev* ftdev; 98 struct ftdev* ftdev;
@@ -110,8 +145,8 @@ static int ftdev_release(struct inode *in, struct file *filp)
110 } 145 }
111 146
112 if (ftdm->readers == 1) { 147 if (ftdm->readers == 1) {
113 /*FIXME: disable events */ 148 while (ftdm->events)
114 ftdm->active_events = 0; 149 deactivate(&ftdm->events, ftdm->events->id);
115 150
116 /* wait for any pending events to complete */ 151 /* wait for any pending events to complete */
117 set_current_state(TASK_UNINTERRUPTIBLE); 152 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -130,7 +165,7 @@ out:
130 return err; 165 return err;
131} 166}
132 167
133/* based on ft_buffer_read 168/* based on ft_buffer_read
134 * @returns < 0 : page fault 169 * @returns < 0 : page fault
135 * = 0 : no data available 170 * = 0 : no data available
136 * = 1 : one slot copied 171 * = 1 : one slot copied
@@ -162,7 +197,7 @@ static ssize_t ftdev_read(struct file *filp,
162 char __user *to, size_t len, loff_t *f_pos) 197 char __user *to, size_t len, loff_t *f_pos)
163{ 198{
164 /* we ignore f_pos, this is strictly sequential */ 199 /* we ignore f_pos, this is strictly sequential */
165 200
166 ssize_t err = 0; 201 ssize_t err = 0;
167 size_t chunk; 202 size_t chunk;
168 int copied; 203 int copied;
@@ -181,7 +216,7 @@ static ssize_t ftdev_read(struct file *filp,
181 len -= chunk; 216 len -= chunk;
182 to += chunk; 217 to += chunk;
183 err += chunk; 218 err += chunk;
184 } else if (copied == 0 && ftdm->active_events) { 219 } else if (copied == 0 && ftdm->events) {
185 /* only wait if there are any events enabled */ 220 /* only wait if there are any events enabled */
186 set_current_state(TASK_INTERRUPTIBLE); 221 set_current_state(TASK_INTERRUPTIBLE);
187 schedule_timeout(50); 222 schedule_timeout(50);
@@ -195,7 +230,7 @@ static ssize_t ftdev_read(struct file *filp,
195 /* page fault */ 230 /* page fault */
196 err = copied; 231 err = copied;
197 break; 232 break;
198 } else 233 } else
199 /* nothing left to get, return to user space */ 234 /* nothing left to get, return to user space */
200 break; 235 break;
201 } 236 }
@@ -239,19 +274,13 @@ static ssize_t ftdev_write(struct file *filp, const char __user *from,
239 goto out_unlock; 274 goto out_unlock;
240 } 275 }
241 /* FIXME: check id against list of acceptable events */ 276 /* FIXME: check id against list of acceptable events */
242 /* FIXME: track which events must be disable at release time */
243 len -= sizeof(cmd_t); 277 len -= sizeof(cmd_t);
244 from += sizeof(cmd_t); 278 from += sizeof(cmd_t);
245 if (cmd == FTDEV_ENABLE_CMD) { 279 if (cmd == FTDEV_DISABLE_CMD)
246 printk(KERN_INFO 280 deactivate(&ftdm->events, id);
247 "Disabling feather-trace event %d.\n", (int) id); 281 else if (activate(&ftdm->events, id) != 0) {
248 ft_disable_event(id); 282 err = -ENOMEM;
249 ftdm->active_events--; 283 goto out_unlock;
250 } else {
251 printk(KERN_INFO
252 "Enabling feather-trace event %d.\n", (int) id);
253 ft_enable_event(id);
254 ftdm->active_events++;
255 } 284 }
256 err += sizeof(cmd_t); 285 err += sizeof(cmd_t);
257 } 286 }
@@ -271,17 +300,18 @@ struct file_operations ftdev_fops = {
271}; 300};
272 301
273 302
274void ftdev_init(struct ftdev* ftdev) 303void ftdev_init(struct ftdev* ftdev, struct module* owner)
275{ 304{
276 int i; 305 int i;
277 ftdev->cdev.owner = THIS_MODULE; 306 cdev_init(&ftdev->cdev, &ftdev_fops);
307 ftdev->cdev.owner = owner;
278 ftdev->cdev.ops = &ftdev_fops; 308 ftdev->cdev.ops = &ftdev_fops;
279 ftdev->minor_cnt = 0; 309 ftdev->minor_cnt = 0;
280 for (i = 0; i < MAX_FTDEV_MINORS; i++) { 310 for (i = 0; i < MAX_FTDEV_MINORS; i++) {
281 mutex_init(&ftdev->minor[i].lock); 311 mutex_init(&ftdev->minor[i].lock);
282 ftdev->minor[i].readers = 0; 312 ftdev->minor[i].readers = 0;
283 ftdev->minor[i].buf = NULL; 313 ftdev->minor[i].buf = NULL;
284 ftdev->minor[i].active_events = 0; 314 ftdev->minor[i].events = NULL;
285 } 315 }
286 ftdev->alloc = NULL; 316 ftdev->alloc = NULL;
287 ftdev->free = NULL; 317 ftdev->free = NULL;
diff --git a/litmus/trace.c b/litmus/trace.c
index 6162bb3716..2ac79a2d8b 100644
--- a/litmus/trace.c
+++ b/litmus/trace.c
@@ -79,7 +79,7 @@ static void free_timestamp_buffer(struct ftdev* ftdev, unsigned int idx)
79static int __init init_ft_overhead_trace(void) 79static int __init init_ft_overhead_trace(void)
80{ 80{
81 printk("Initializing Feather-Trace overhead tracing device.\n"); 81 printk("Initializing Feather-Trace overhead tracing device.\n");
82 ftdev_init(&overhead_dev); 82 ftdev_init(&overhead_dev, THIS_MODULE);
83 overhead_dev.minor_cnt = 1; /* only one buffer */ 83 overhead_dev.minor_cnt = 1; /* only one buffer */
84 overhead_dev.alloc = alloc_timestamp_buffer; 84 overhead_dev.alloc = alloc_timestamp_buffer;
85 overhead_dev.free = free_timestamp_buffer; 85 overhead_dev.free = free_timestamp_buffer;