diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-09-17 14:29:31 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-09-17 14:29:31 -0400 |
commit | aeb7a10b15401c80fc1c5ecf93b1e22240f046e6 (patch) | |
tree | 011952ec7f286dbea2316322394994c8ff1d5452 | |
parent | 364619e98672692ad1f58d96ffab531a304868e5 (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.h | 8 | ||||
-rw-r--r-- | litmus/ftdev.c | 72 | ||||
-rw-r--r-- | litmus/trace.c | 2 |
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; | |||
16 | typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no); | 16 | typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no); |
17 | typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no); | 17 | typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no); |
18 | 18 | ||
19 | struct ftdev_event; | ||
20 | |||
19 | struct ftdev_minor { | 21 | struct 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 | ||
26 | struct ftdev { | 29 | struct 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 { | |||
36 | struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size); | 38 | struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size); |
37 | void free_ft_buffer(struct ft_buffer* buf); | 39 | void free_ft_buffer(struct ft_buffer* buf); |
38 | 40 | ||
39 | void ftdev_init(struct ftdev* ftdev); | 41 | void ftdev_init(struct ftdev* ftdev, struct module* owner); |
40 | int register_ftdev(struct ftdev* ftdev, const char* name, int major); | 42 | int 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 | ||
61 | struct ftdev_event { | ||
62 | int id; | ||
63 | struct ftdev_event* next; | ||
64 | }; | ||
65 | |||
66 | static 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 | |||
80 | static 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 | |||
61 | static int ftdev_open(struct inode *in, struct file *filp) | 96 | static 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 | ||
274 | void ftdev_init(struct ftdev* ftdev) | 303 | void 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) | |||
79 | static int __init init_ft_overhead_trace(void) | 79 | static 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; |